Swift对接Firebase时强制解包querySnapshot是否合理,有无更优方案
Swift & Firestore 代码问题解答
强制解包是否为合理实践
该场景下不建议使用强制解包,不属于合理的开发实践:
- 虽然Firebase SDK的常规回调逻辑中,
error不为空时querySnapshot才会为nil,反之亦然,但该约定仅为SDK层面的逻辑约定,无编译器层面的强保证。极端场景下(如SDK版本迭代修改回调逻辑、异常网络状态触发SDK未覆盖的分支)仍可能出现error为空但querySnapshot也为nil的情况,此时强制解包会直接触发闪退,无任何容错空间。
更优的解决方案
1. 可选绑定解包(最推荐)
在else分支中对querySnapshot做可选绑定,完全规避空值风险,同时可覆盖异常分支的处理逻辑:
COLLECTION_USERS.whereField("username", isEqualTo: username).getDocuments { (querySnapshot, error) in if let error = error { print("Error connecting to database: \(error.localizedDescription)") } else if let snapshot = querySnapshot { if snapshot.isEmpty { print("SIGNED UP") } } else { // 自定义异常分支逻辑 print("Unknown error: no error returned but snapshot is nil") } }
2. 空合运算符简化判断
如果不需要单独处理双空异常分支,可使用空合运算符给空快照提供默认判断值,简化写法:
COLLECTION_USERS.whereField("username", isEqualTo: username).getDocuments { (querySnapshot, error) in if let error = error { print("Error connecting to database: \(error.localizedDescription)") } else { if querySnapshot?.isEmpty ?? true { print("SIGNED UP") } } }
该写法逻辑为:若querySnapshot为空,默认视为isEmpty为true,符合原有逻辑的判断预期。
3. guard语句提前退出
如果后续存在更多和快照相关的业务逻辑,可使用guard语句提前退出,减少代码嵌套层级:
COLLECTION_USERS.whereField("username", isEqualTo: username).getDocuments { (querySnapshot, error) in if let error = error { print("Error connecting to database: \(error.localizedDescription)") return } guard let snapshot = querySnapshot else { print("Unknown error: snapshot is nil") return } if snapshot.isEmpty { print("SIGNED UP") } }
内容的提问来源于stack exchange,提问作者Jacob
相关产品推荐
相关产品推荐

