SwiftUI는 iOS 애플리케이션의 사용자 인터페이스를 개발하는 데 사용되는 강력한 프레임워크입니다. SwiftUI 앱에서 네트워크 호출, 파일 다운로드 등 비동기 작업을 수행해야 할 때가 있습니다.
이 글에서는 SwiftUI에서 비동기 작업을 수행하는 방법을 살펴보겠습니다.
1. 비동기 작업 처리를 위한 AsyncImage
Swift 5.5 버전부터 SwiftUI에는 AsyncImage
라는 이미지 뷰가 추가되었습니다. 이를 통해 이미지를 비동기적으로 다운로드하고 로드할 수 있습니다.
AsyncImage(url: URL(string: "https://example.com/image.jpg")) { image in
image.resizable()
.aspectRatio(contentMode: .fit)
} placeholder: {
ProgressView()
}
AsyncImage
는 URL
을 받아서 해당 URL에서 이미지를 비동기적으로 다운로드하고, 로딩 중에는 placeholder
로 지정한 뷰를 보여줍니다.
2. 비동기 작업 처리를 위한 Task와 Async/Await
Swift 5.5부터는 SwiftUI와 함께 async/await
와 Task
를 사용하여 비동기 작업을 쉽게 처리할 수 있습니다.
struct ContentView: View {
@State private var data: [Item] = []
var body: some View {
List(data, id: \.id) { item in
Text(item.title)
}
.task {
do {
data = try await fetchData()
} catch {
print("Error fetching data: \(error)")
}
}
}
func fetchData() async throws -> [Item] {
// 비동기 데이터 가져오기
return items
}
}
위의 예제에서 ContentView
는 data
라는 상태를 가지고 있고, 해당 데이터를 비동기적으로 가져오기 위해 async
키워드를 사용한 fetchData
메서드를 정의하였습니다. 또한, List
의 task
블록 내에서 데이터를 비동기적으로 가져오도록 구현되어 있습니다.
3. 비동기 작업 처리를 위한 Combine 및 URLSession
또 다른 방법은 SwiftUI와 Combine 프레임워크를 사용하여 네트워크 호출을 처리하는 것입니다. 예를 들어, URLSession
을 사용하여 비동기적으로 데이터를 가져올 수 있습니다.
struct ContentView: View {
@State private var data: [Item] = []
var body: some View {
List(data, id: \.id) { item in
Text(item.title)
}
.onAppear {
fetchData()
}
}
func fetchData() {
URLSession.shared.dataTaskPublisher(for: URL(string: "https://api.example.com/data")!)
.map(\.data)
.decode(type: [Item].self, decoder: JSONDecoder())
.receive(on: DispatchQueue.main)
.sink { completion in
// handle completion
} receiveValue: { newData in
data = newData
}
.store(in: &cancellables)
}
}
위의 예제에서, ContentView
는 onAppear
modifier를 사용하여 뷰가 나타날 때 데이터를 가져오도록 되어 있습니다. fetchData
메서드에서 URLSession
을 사용하여 데이터를 가져오고, Combine 프레임워크의 sink
를 사용하여 데이터를 처리합니다.
마무리
SwiftUI에서의 비동기 작업을 위해 AsyncImage
, async/await
및 Task
, Combine 및 URLSession과 같은 다양한 방법을 살펴보았습니다. 앱의 요구에 맞게 적합한 방법을 선택하여 SwiftUI앱에서 원활하게 비동기 작업을 처리할 수 있을 것입니다.
출처: