SwiftUI API 통신: 외부 라이브러리 없이 모듈화해보기
SwiftUI API 통신: 외부 라이브러리 없이 모듈화해보기
SwiftUI는 사용자 인터페이스를 작성하는 현대적인 방법을 제공하지만, 네트워크 요청을 처리하고 데이터를 관리하는 방법에 대한 별도의 라이브러리는 제공하지 않습니다. 하지만 Swift의 강력한 Codable
과 URLSession
을 활용하면 외부 라이브러리 없이도 네트워크 통신을 효과적으로 모듈화할 수 있습니다. 이 글에서는 그 구체적인 방법을 설명합니다.
1. 모델(Model) 정의하기
먼저, 네트워크 요청에서 받을 데이터를 표현할 모델을 정의합니다. Swift의 Codable
프로토콜을 사용하여 JSON 데이터를 손쉽게 변환할 수 있습니다.
swiftstruct Post: Codable, Identifiable { let id: Int let title: String let body: String }
위의 모델은 id
, title
, body
라는 세 가지 속성을 가진 Post
구조체를 정의합니다.
2. 네트워크 레이어 만들기
다음으로, 네트워크 요청을 처리할 클래스를 만듭니다. 모듈화를 위해 이 클래스를 별도의 파일에 정의하는 것이 좋습니다. 여기서는 URLSession을 사용해 보겠습니다.
swiftimport Foundation class NetworkManager { static let shared = NetworkManager() private let baseURL = "https://jsonplaceholder.typicode.com" private init() {} func fetchPosts(completion: @escaping ([Post]?) -> Void) { guard let url = URL(string: "\(baseURL)/posts") else { completion(nil) return } let task = URLSession.shared.dataTask(with: url) { data, response, error in guard let data = data, error == nil else { completion(nil) return } let posts = try? JSONDecoder().decode([Post].self, from: data) completion(posts) } task.resume() } }
네트워크 매니저 클래스는 싱글톤 패턴을 사용하여 인스턴스를 관리합니다. fetchPosts
메서드는 네트워크 요청을 보내고, 결과를 디코딩한 후 완료 핸들러를 통해 반환합니다.
3. ViewModel 정의하기
네트워크에서 받아온 데이터를 SwiftUI에서 사용하려면 ViewModel을 정의해야 합니다. 이 ViewModel은 네트워크 매니저를 사용하여 데이터를 가져옵니다.
swiftimport Combine class PostViewModel: ObservableObject { @Published var posts = [Post]() private var cancellables = Set<AnyCancellable>() init() { fetchPosts() } func fetchPosts() { NetworkManager.shared.fetchPosts { [weak self] posts in guard let self = self else { return } DispatchQueue.main.async { self.posts = posts ?? [] } } } }
ViewModel 클래스는 ObservableObject
를 채택하여 뷰와 데이터를 연결합니다. 네트워크 요청이 완료되면 UI가 업데이트됩니다.
4. SwiftUI View에서 ViewModel 사용하기
이제 최종적으로 SwiftUI View에서 ViewModel을 사용하여 데이터를 표시해 봅시다.
swiftimport SwiftUI struct ContentView: View { @StateObject private var viewModel = PostViewModel() var body: some View { NavigationView { List(viewModel.posts) { post in VStack(alignment: .leading) { Text(post.title) .font(.headline) Text(post.body) .font(.subheadline) } } .navigationTitle("Posts") } .onAppear { viewModel.fetchPosts() } } }
ContentView
는 PostViewModel
인스턴스를 생성하고, List
뷰에서 포스트 데이터를 표시합니다. 네트워크 요청은 onAppear
이벤트에서 호출됩니다.
5. 결론
이 글에서는 SwiftUI에서 외부 라이브러리를 사용하지 않고 API 통신을 모듈화하는 방법을 다뤘습니다. 네트워크 매니저, ViewModel, 그리고 뷰를 분리하여 각 부분의 역할을 명확히 하고 유지보수가 용이하게 만들었습니다. Swift의 강력한 내장 기능을 활용하면 이러한 작업을 쉽게 수행할 수 있습니다.