我有一个从Firebase加载数据的代码,数据不是立即加载的,我想首先加载数据,然后将数据传递给委托. 为此,我使用了WAIT构造和同步加载数据函数

let dateUser = await loadData(phoneNumber: phoneNumber)

根据这个 idea ,dateUser变量应该等到函数返回结果,但函数不等待数据加载就立即返回结果

你能告诉我错误是什么吗,我认为你需要在loadData函数内部等待,但在哪里?

到处都有如何使用此构造加载JSON文件的示例,但我没有找到它在闭包中的什么地方使用

以下是一个示例代码

struct LoadData {
    
    let db = Firestore.firestore()
    var delegate: LoadDataDelegate?    
    
    func getData(phoneNumber:String){
        Task.init {
            let dateUser = await loadData(phoneNumber: phoneNumber)
            print("Делегат получил дату - ", dateUser)
            delegate!.loadData(date: dateUser)
        }
    }
    
    func loadData(phoneNumber: String) async -> TimeInterval? {
        
        var existingUser = false /// Проверка существует ли пользователь с данным номером телефона в базе
        var date: TimeInterval?
        
        db.collection("Users").getDocuments { QuerySnapshot, Error in
            if let err = Error {
                print("Ошибка получения данных - \(err)")
            }
            
            for document in QuerySnapshot!.documents {
                
                if document.documentID == phoneNumber { /// Если текущий пользователь уже был зарегестрирован
                    
                    existingUser = true
                    date =  document["dateFirstLaunch"] as? TimeInterval /// Преобразуем данные из FireBase
                    print("это дата ",date!)
                    
                }
            }
            
            if existingUser == false { /// Если такого пользователя не было
                
                print("New User")
                db.collection("Users").document(phoneNumber).setData(["dateFirstLaunch" : NSDate().timeIntervalSince1970]) { error in
                    if let  err = error {
                        print("Ошибка записи данных в обалко - \(err)")
                    }
                }
            }
        }
        
        return date
        
    }
    
}

protocol LoadDataDelegate {
    func loadData(date: TimeInterval?)
    
}

我试图在loadData函数内部等待,但结果要么出现错误,要么什么都不起作用

推荐答案

您没有对loadData中的任何异步操作执行await操作,因此loadData立即返回.

您应该使用async个版本的Firebase FiRestore API,而不是那些带有完成处理程序的API.

不是传递完成处理程序,而是try await异步操作.只需将代码放入完成处理程序aftertry await行,并使用catch块处理错误.

例如:

func loadData(phoneNumber: String) async -> TimeInterval? {
    do {
        let querySnapshot = try await db.collection("Users").getDocuments()
        for document in querySnapshot.documents {
            if document.documentID == phoneNumber {
                return document["dateFirstLaunch"] as? TimeInterval
            }
        }
    } catch {
        print("Ошибка получения данных - \(error)")
        // I assume you want to return nil immediately in this case and not write to the document
        return nil
    }
    print("New User")
    do {
        try await db.collection("Users").document(phoneNumber).setData(["dateFirstLaunch" : Date().timeIntervalSince1970])
    } catch {
        print("Ошибка записи данных в обалко - \(error)")
    }
    // I assume that in the new user case, you want to return nil
    return nil
}

Swift相关问答推荐

VisionOS发送通知

字符串目录不适用于SWIFT包

按变换zoom 在UIView中不起作用

如何在SWIFT中使用DiscardingTaskGroup获得任务结果

在SWIFT中使用Objective-C struct 时出错(在作用域中找不到类型)

为什么枚举上的.allCases.forEach不是循环(继续和中断不起作用)?

Swift数据关系

使第二个视图变灰 SwiftUI

为什么 SwiftUI 中 ForEach 的这个 Select 不起作用?

如何在 switch case 模式语句中使用 Swift 文字正则表达式?

Vapor 4 身份验证问题 [用户未通过身份验证]

Xcode swift ui 错误KeyPathComparator仅在 macOS 12.0 或更高版本中可用

不支持用作符合协议 AnyObject 的具体类型

在 Swift for iOS 中沿圆形路径绘制文本

哪些版本的 Xcode 支持哪些版本的 Swift?

如何以编程方式读取 wkwebview 的控制台日志(log)

如何在 Swift 中将 NSURL 转换为字符串

如何在 Swift 中判断变量的类型

SwiftUI:将多个 BindableObjects 放入环境

如何快速从另一个视图控制器重新加载表格视图