我在 Swift/SwiftUI 中復制了以下示例。我只是想從firebase中提取2個“評級”,然后在加載后顯示它們。我有 2 種可能的方法來加載以下評級。
方法一:等待資料加載,加載后顯示。但是,我的問題是這段代碼沒有加載資料,我的評級串列仍然是空的。但是,資料庫不會引發任何錯誤。
方法二:不用等待資料加載,而是使用一個定時器,簡單地等待2秒,希望到那時資料加載完畢再顯示。
方法1是我想要做的作業。但是,方法 2 有效,所以我知道這不是資料庫或我的資料的問題,但很可能是我的 async/await 使用的問題。
下面是我復制的代碼。看起來很多,但沒什么瘋狂的,對不起!
struct test: View {
@State var ratings: [Double] = []
@State var ratingsAreLoading = true
func getRatings() async {
let db = Firestore.firestore() //database object
await db.collection("users").document("user 1).getDocument { (doc, error) in
if let doc = doc { //just gets some data
ratings.append(doc["rating1"] as? Double ?? 1.0)
ratings.append(doc["rating2"] as? Double ?? 1.0)
}
}
}
var body: some View {
VStack {
if ratingsAreLoading {
Text("LOADING...")
} else {
Text(String(ratings[0])) //displays a rating
}
}
//IMPLEMENTATION HERE
}
}
方法 1:似乎沒有填充“評級”串列
.task {
await getRatings() //gets ratings
await MainActor.run {
ratingsAreLoading = false //displays the ratings
}
}
方法2:有效
.onAppear {
getRatings() //gets ratings
DispatchQueue.main.asyncAfter(deadline: .now() 2) {
ratingsAreLoading = false //displays ratings after 2 seconds
}
}
我對 async/await 方法做錯了什么?我怎樣才能讓它及時或根本加載我的資料?
uj5u.com熱心網友回復:
您必須將完成處理程式轉換為與async await
它看起來像這樣
///Retrieves a single document with the provided id at the collection's path
public func retrieve<FC : FirestoreCodable>(path: String, id: String) async throws -> FC{
typealias MyContinuation = CheckedContinuation<FC, Error>
return try await withCheckedThrowingContinuation { (continuation: MyContinuation) in
let docRef = store.collection(path).document(id)
docRef.getDocument(as: FC.self){
result in
switch result{
case .success(let object):
continuation.resume(returning: object)
case .failure(let error):
continuation.resume(throwing: error)
}
}
}
}
為了補充上面的代碼,我在class/struct級別放置了一個屬性
private let store : Firestore
這樣您就可以添加任何設定代碼,init例如isPersistenceEnabled
FirestoreCodable只是protocol幫助泛型
public protocol FirestoreCodable: Decodable, Encodable{
/// Wrap with `@DocumentID` from `import FirebaseFirestoreSwift`
var id: String? { get set }
}
你struct會看起來像
struct User: FirestoreCodable{
@DocumentID var id: String?
var rating1: Double
var rating2: Double
}
你會用它像
let user: User = try await retrieve(path: "users", id: "user 1")
您可以找到更多關于async/await我的 WWDC21 視頻
https://developer.apple.com/wwdc21/10132
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/479886.html
