我一直在使用下面的 Google Firebase 方法,在用户打开视图控制器时加载用户数据,但是它无法工作,因为我收到错误“在不支持并发的函数中调用‘异步’”和“将“async”添加到函数“viewDidLoad()”以使其异步”,这只会进一步产生问题。这是下面的代码,请告诉我如何才能克服这个(它必须在 viewDidLoad() 中)
override func viewDidLoad() async {
super.viewDidLoad()
let db = Firestore.firestore()
let docRef = db.collection("cities").document("SF")
do {
// Force the SDK to fetch the document from the cache. Could also specify
// FirestoreSource.server or FirestoreSource.default.
let document = try await docRef.getDocument(source: .cache)
if document.exists {
let dataDescription = document.data().map(String.init(describing:)) ?? "nil"
print("Cached document data: \(dataDescription)")
} else {
print("Document does not exist in cache")
}
} catch {
print("Error getting document: \(error)")
}
}
我尝试了各种方法来尝试减少问题,例如使用“Task {}”方法重新创建保存方法,但是这会导致 QuerySnapshot 出现问题(QuerySnapshot 位于我的个人代码中,而不是在代码中)我还回顾了 Google Firebase 实现的其他方法,它们都具有“尝试等待”编码单元,所以我试图找到一种解决 View did load 的方法。
我还想确认一下,由于 Stack Overflow 团队不断纠缠我提出“重复”问题,这些问题与我的问题实际上没有 0 相关性,事实上这个问题不是重复的,在这个平台上没有得到回答,不是转发,并且在这个平台之外无法得到答案(至少从我的搜索来看。)
首先,这是行不通的:
override func viewDidLoad() async {
viewDidLoad
不是异步方法。仅通过添加 async
无法使其成为异步方法。 viewDidLoad()
必须在返回时完成,并且必须是同步的。这就是该方法的本质,它不仅早于 Swift Concurrency,而且早于 Swift。
如果您想在
viewDidLoad()
期间创建异步上下文,可以使用 Task {}
来实现,例如:
override func viewDidLoad() {
super.viewDidLoad()
let db = Firestore.firestore()
let docRef = db.collection("cities").document("SF")
Task {
do {
... everything else
}
}
这并不保证任务将在
viewDidLoad()
返回之前完成。 (绝对不会。)但这将在viewDidLoad
期间开始工作。
可能引起混乱的是,根据设计,不可能在网络呼叫进行时避免显示“某些内容”。想象一下,如果网络调用需要几分钟才能完成,然后返回错误怎么办?在此期间和发生错误之后,您的系统会显示什么?你必须处理这种情况。在获得来自网络的数据之前,您不能只是阻止加载视图。它可能永远不会到来。因此,您必须显示一些内容,当网络数据显示时,您将更新视图。