동시성 프로그래밍 키워드인 await와 async를 SwiftUI에서 사용하는 법에 대해 알아보려고 한다.
await와 async 키워드를 사용하는 코드를 먼저 작성해보자.
아래와 같은 싱글톤 NetworkManager를 만들어보자
class NetworkManager {
let baseURL = "{URL}"
static let shared: NetworkManager = NetworkManager()
// async 한다고 꼭 throws/try를 쓸 필요는 없다.
func requestAsync() async -> [Step] {
guard let url = URL(string: self.baseURL) else {
return []
}
do {
let urlRequest = URLRequest(url: url)
let (data, _) = try await URLSession.shared.data(for: urlRequest)
let stepList = try JSONDecoder().decode([Step].self, from: data)
return stepList
} catch (let e) {
// Error handling
print(e)
}
return []
}
}
비동기처리가 이뤄질(await/async 기능이 있는) 함수는 async 키워를 붙이면 된다.
SwiftUI에서 사용된다고 생각해보자.
struct NetworkView: View {
@State private var stepList: [Step] = []
let viewModel: NetworkManager = NetworkManager.shared
var body: some View {
VStack {
Button("Get Step await") {
Task {
self.stepList = await self.viewModel.requestAsync()
}
}
List(self.stepList, id: \.title) { step in
Text("\(step.title): \(step.content)")
}
}
}
}
Task라는 것을 사용했다.

priority와 throws가 Optional이다.
위의 코드는 throws 처리가 없지만, 만약 requestAsync에서 do-catch 처리를 하지 않았다면?
func requestAsyncTry() async throws -> [Step] {
let urlRequest = URLRequest(url: url)
let (data, _) = try await URLSession.shared.data(for: urlRequest)
let stepList = try JSONDecoder().decode([Step].self, from: data)
return stepList
}
함수에는 async뒤에 throws 키워만 붙여주면 된다.
그리고 오류를 던지고 있으니, Task에서 사용할 때
Task {
self.stepList = try await self.viewModel.requestAsyncTry()
}
try를 앞에 붙여주기만 하면된다.
UIKit에서는 아직 안 써봤지만, SwiftUI에서는 쓰는데 그렇게 어렵진 않아보인다!
Swift.org에는 Concurrency 페이지에 Task, Actor 등의 키워드들이 있는데, 아직 제대로 사용할 정도로 이해하진 못했다.
'iOS > Swift' 카테고리의 다른 글
[Swift] HOF(Higher Order Function) (2) (0) | 2022.08.03 |
---|---|
[Swift] HOF(Higher Order Function) (1) (0) | 2022.08.03 |
[Swift] 클래스 (0) | 2022.06.24 |
[Swift] 구조체 (0) | 2022.06.16 |
[Swift] Optional(옵셔널) (0) | 2022.06.09 |