使用Firestore加载用户数据时出现下载暂停问题求助
解决Firestore数据下载暂停的问题
嘿,这个问题我太熟悉了!你现在的代码逻辑有个关键问题:Firestore的文档读取是异步操作,你的三个loadingFunction会立刻返回,不会等数据下载完成,而你紧接着就调用了performSegue——这就导致视图控制器被销毁,Firestore的下载任务自然就暂停了。
下面给你两种常用的解决方案,按需选择:
方案一:用DispatchGroup等待所有异步任务完成
这种方法兼容所有iOS版本,核心是用DispatchGroup来追踪三个加载任务的完成状态,等全部完成后再执行跳转:
override func viewDidLoad() { super.viewDidLoad() let loadGroup = DispatchGroup() // 每个加载任务开始前标记进入group loadGroup.enter() loadingFunction1 { // 任务完成后标记离开group loadGroup.leave() } loadGroup.enter() loadingFunction2 { loadGroup.leave() } loadGroup.enter() loadingFunction3 { loadGroup.leave() } // 当所有任务都离开group后,在主线程执行跳转 loadGroup.notify(queue: .main) { self.performSegue(withIdentifier: "goToNextScreen", sender: nil) } } // 给加载函数添加完成回调 func loadingFunction1(completion: @escaping () -> Void) { let docRef = Firestore.firestore().collection("yourCollection").document("yourDocId") docRef.getDocument { snapshot, error in if let error = error { print("加载数据失败:\(error.localizedDescription)") // 即使出错也要调用completion,避免group一直等待 completion() return } // 解析并存储数据... completion() } } // 同理修改loadingFunction2和loadingFunction3,添加completion回调
方案二:用async/await(iOS 15+ / Swift 5.5+)
如果你的项目支持iOS 15及以上,用async/await会让代码更简洁易读,原生支持并发等待:
override func viewDidLoad() { super.viewDidLoad() // 启动一个异步任务 Task { do { // 并发执行三个加载任务 async let data1 = loadingFunction1() async let data2 = loadingFunction2() async let data3 = loadingFunction3() // 等待所有任务完成,获取结果 let (result1, result2, result3) = try await (data1, data2, data3) // 这里可以处理获取到的三个结果... // 回到主线程执行跳转(UI操作必须在主线程) DispatchQueue.main.async { self.performSegue(withIdentifier: "goToNextScreen", sender: nil) } } catch { print("加载数据出错:\(error.localizedDescription)") // 这里可以处理错误,比如显示提示给用户 } } } // 将加载函数改为async函数 func loadingFunction1() async throws -> YourDataModel { let docRef = Firestore.firestore().collection("yourCollection").document("yourDocId") let snapshot = try await docRef.getDocument() // 解析快照到你的数据模型 guard let data = snapshot.data(), let model = YourDataModel(dictionary: data) else { throw NSError(domain: "DataParsingError", code: 0, userInfo: [NSLocalizedDescriptionKey: "无法解析数据"]) } return model } // 同理修改loadingFunction2和loadingFunction3,返回对应的数据模型
额外注意事项
- 一定要处理Firestore的错误,不管是用回调还是
do-catch,避免出现任务卡住或者崩溃的情况 - 如果你的加载函数用的是
addSnapshotListener(实时监听),而不是单次读取getDocument,要确保在跳转前已经设置好监听,并且在合适的时机移除监听(比如在viewWillDisappear里) - 可以在Loading视图里加个加载指示器(比如
UIActivityIndicatorView),在开始加载时显示,所有任务完成后隐藏,提升用户体验
内容的提问来源于stack exchange,提问作者August W Danowski
相关产品推荐
相关产品推荐

