Swift中为Firebase的addDocument函数编写Completion Handler的方法
正确封装适配Firebase addDocument的Completion Handler
首先给出修正后的可运行完整代码:
// 上层调用代码 self.addDocument(data: [fullname, username, result!.user.uid]) { error in if let error = error { self.showError("Error saving user's data: \(error.localizedDescription)") } // 操作成功的后续逻辑可以在这里添加 } // 封装的Firebase操作函数 func addDocument(data: [String], completionHandler: ((Error?) -> Void)? = nil) { let db = Firestore.firestore() db.collection("users").addDocument(data: [ "fullname": data[0], "username": data[1], "uid": data[2] ]) { error in // 将Firebase返回的结果透传给上层的completionHandler completionHandler?(error) } }
原代码存在两个核心问题:
- 异步操作的结果全部通过completion回调传递,不需要额外定义返回值,你之前写的
as! Error强制类型转换是错误写法,运行时必然崩溃 - 原代码内部Firebase的回调闭包为空,没有调用传入的
completionHandler,导致上层永远收不到操作结果
实现运行原理
- 异步回调机制:Firebase的
addDocument属于网络IO异步任务,执行时不会阻塞当前主线程,等到网络请求完成(写入成功/失败)后,才会触发内部的回调闭包返回结果 - 能力隔离逻辑:所有Firebase相关的依赖(初始化Firestore、指定collection、拼接请求参数)都被封装在
addDocument函数内部,上层调用方只需要传入待存储数据、实现结果处理闭包即可,完全感知不到底层使用的是Firebase还是其他后端服务。后续切换服务时只需要修改这个函数内部的实现,上层所有调用代码都不需要调整,符合可扩展的设计要求 - Completion Handler的传递逻辑:你定义的
completionHandler是上层调用方传入的回调闭包,用来接收操作结果。当Firebase的任务执行完成拿到error参数后,把这个参数直接透传给completionHandler就完成了底层结果向上层的传递,如果error为nil就代表操作成功。
优化建议
- 可以把入参从
[String]改成自定义结构体或者[String: Any]类型,避免按索引取数据时容易传错顺序的问题 - 可以在completion中增加成功回传值,比如成功时返回生成的文档ID,方便上层业务使用
内容的提问来源于stack exchange,提问作者Туе Нгуен
相关产品推荐
相关产品推荐

