Firestore NSArray 到 Swift.Array 匹配错误
Posted
技术标签:
【中文标题】Firestore NSArray 到 Swift.Array 匹配错误【英文标题】:Firestore NSArray to Swift.Array match error 【发布时间】:2019-05-18 17:54:03 【问题描述】:我在使用 Firebase/Firestore SDK 时遇到了问题:
前提条件失败:NSArray 元素未能匹配 Swift Array 元素类型 预期 FIRQueryDocumentSnapshot 但发现 FIRQueryDocumentSnapshot:文件 /BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-1001.2.63.12/swift/stdlib/public/core/ArrayBuffer.swift,第 346 行 2019-05-18 19:46:00.020040+0200 App[25051:288337] 前提条件失败:NSArray 元素未能匹配 Swift Array 元素类型 预期的 FIRQueryDocumentSnapshot 但找到了 FIRQueryDocumentSnapshot:文件 /BuildRoot/Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-1001.2.63.12/swift/stdlib/public/core/ArrayBuffer.swift,第 346 行
let listener = self.client
.collection("countries/czechia/cities/\(id.rawValue)/venues")
.addSnapshotListener( (snapshot, error) in
guard let docs = snapshot?.documents else
observer.onError(error!)
return
let arr: [Venue] = docs.compactMap doc in // The code crashes on this line
do
let decoded = try self.decoder.decode(Venue.self, from: doc.data())
return decoded
catch
print(error)
return nil
【问题讨论】:
永远不要在警戒线中以这种方式注释类型:guard let docs: [QueryDocumentSnapshot] = snapshot?.documents else
。条件向下转换类型:guard let docs = snapshot?.documents as? [QueryDocumentSnapshot] else
是的,对不起,这是为了调试目的,我删除了它,无论如何代码仍然表现相同
试试let arr = docs.compactMap doc -> Venue? in
这没有帮助,当我开始迭代 docs
数组时,问题就出现了
【参考方案1】:
当您使用伞式框架技术时,此错误非常常见。 我得到“Precondition failed: NSArray element failed to match the Swift Array Element type 预期为 FIRQueryDocumentSnapshot,但发现 FIRQueryDocumentSnapshot bla bla bla bla...“尽管只有一个对静态框架的 Firebase 实例引用正常工作。
所以我不得不使用强大的 NSObject 功能,特别是键值编码协议。
检查一下……
let db = Firestore.firestore(app: firebase_instance)
defaultsHelper.write(value: true, key: .isReceivingProspects)
prospectosListener = db.collection("collection_name")
.document("document_name")
.collection("collection_name")
.whereField("condition_parameter", arrayContains: "condition_value")
.addSnapshotListener querySnapshot, error in
weak var _self = self
guard let snapshot = querySnapshot else
print("Error fetching document: \(error!)")
return
// snapshot.documents or snapshot.documentChanges in a loop produces crash
guard let documents = (snapshot as NSObject).value(forKey: "documentChanges") as? NSArray else return
for document in documents
guard let object = document as? NSObject else debugPrint("object was nil"); return
guard let type = object.value(forKey: "type") as? Int else debugPrint("type was nil"); return
guard let docs = object.value(forKey: "document") as? NSObject else debugPrint("document was nil"); return
guard let data = docs.value(forKey: "data") as? [String: Any] else debugPrint("data was nil"); return
guard let fbModel = _self?.documentConverter.convertToNotificationModel(documentData: data) else
debugPrint("fbModel was nil")
return
switch type
case 0: // Added
_self?.onAddedOrModifiedNotificationEvent(fbModel: fbModel)
case 1: // Modified
_self?.onAddedOrModifiedNotificationEvent(fbModel: fbModel)
case 2: // Removed
_self?.onDeleteNotificationEvent(fbModel: fbModel)
default:
debugPrint("Another option")
【讨论】:
以上是关于Firestore NSArray 到 Swift.Array 匹配错误的主要内容,如果未能解决你的问题,请参考以下文章
将数据从 Firestore 映射到 Swift 中的结构 - IOS