📡
通信処理をSwift Concurrencyで記載する
こちらの記事では無名関数をつかって通信処理を切り分けましたが
最近登場しました Swift Concurrency をつかって処理を考えてみます。
前回はこのようなコードを作成しました。
override func viewDidLoad() {
super.viewDidLoad()
getUsers { [weak self] queryDocumentSnapshot in
self?.showUsers(queryDocumentSnapshot: queryDocumentSnapshot)
}
}
func getUsers(completion: @escaping ([QueryDocumentSnapshot]) -> Void) {
let db = Firestore.firestore()
db.collection("users").getDocuments { (querySnapshot, err) in
if let err = err {
print("Error getting documents: \(err)")
} else {
let userDocuments = querySnapshot!.documents
completion(userDocuments)
}
}
}
func showUsers(queryDocumentSnapshot: [QueryDocumentSnapshot]) {
// ここに userDocuments を使うコードが書いてある
}
この例では Firebase Firestore を利用しています。
Firestore もいずれ Swift Concurrency に正式対応するタイミングがあるかと思いますが
このように現時点では Closure で実装されたコードと Swift Concurrency を組み合わせるには
withCheckedThrowingContinuation を使用します。
次に、この実装を示します。
override func viewDidLoad() {
super.viewDidLoad()
Task {
do {
async let userDocuments = getUsers()
showUsers(userDocuments: try await userDocuments)
} catch {
print(error)
}
}
}
func getUsers() async throws -> [QueryDocumentSnapshot] {
try await withCheckedThrowingContinuation { continuation in
let db = Firestore.firestore()
db.collection("users").getDocuments { (querySnapshot, error) in
if let error = error {
continuation.resume(throwing: error)
} else {
let userDocuments = querySnapshot!.documents
continuation.resume(returning: userDocuments)
}
}
}
}
func showUsers(userDocuments: [QueryDocumentSnapshot]) {
// ここに userDocuments を使うコードが書いてある
}
参考資料
Discussion