如何在 Swift 5 中将文档转换为自定义对象?
Posted
技术标签:
【中文标题】如何在 Swift 5 中将文档转换为自定义对象?【英文标题】:How to convert document to a custom object in Swift 5? 【发布时间】:2020-04-20 06:16:25 【问题描述】:我一直在尝试将从 Firebase 的 Cloud Firestore 检索到的文档转换为 Swift 5 中的自定义对象。我正在关注文档:
https://firebase.google.com/docs/firestore/query-data/get-data#custom_objects但是,Xcode 向我显示了 Value of type 'NSObject' has no member 'data'
行的错误 try $0.data(as: JStoreUser.self)
。我将结构定义为Codable
。
代码:
func getJStoreUserFromDB()
db = Firestore.firestore()
let user = Auth.auth().currentUser
db.collection("users").document((user?.email)!).getDocument()
(document, error) in
let result = Result
try document.flatMap
try $0.data(as: JStoreUser.self)
用户结构:
public struct JStoreUser: Codable
let fullName: String
let whatsApp: Bool
let phoneNumber: String
let email: String
let creationDate: Date?
截图:
有谁知道如何解决这个问题?
【问题讨论】:
只需使用 Firestore 返回的字典初始化自定义对象 我不确定你在.getDocument()
完成处理程序中做了什么,但我认为你需要将通过 guard let json = let json = try JSONSerialization.jsonObject(with: document.data(), options: []) as? [String:[String:Any]]
返回的 Data
转换为字典,或者类似的东西(您的数据的结构可能不是[String:[String:Any]]
)。从那里,您可以获取各个值并从这些值中初始化一个对象。正如 bsod 所提到的,您还可以在初始化程序中传递一个字典并以这种方式初始化一个对象。
等等,我正在查看您正在复制文档的哪一部分。我使用实时数据库,将请求返回的Data
通过JSONSerialization.jsonObject
转换为字典没有问题。只要请求返回的是 JSON 数据,你应该可以通过这个方法将它转换成一个对象。
这将有助于理解您在这里尝试做什么 - 您正在阅读的 Firestore 结构是什么样的以及 JStoreUser 类是什么?您是否正在尝试从 Firestore 文档中获取数据并从中制作 Swift 结构?注意这个 $0.data
是一个字典 你可以这样做:-
首先创建模型类:-
import FirebaseFirestore
import Firebase
//#Mark:- Users model
struct CommentResponseModel
var createdAt : Date?
var commentDescription : String?
var documentId : String?
var dictionary : [String:Any]
return [
"createdAt": createdAt ?? "",
"commentDescription": commentDescription ?? ""
]
init(snapshot: QueryDocumentSnapshot)
documentId = snapshot.documentID
var snapshotValue = snapshot.data()
createdAt = snapshotValue["createdAt"] as? Date
commentDescription = snapshotValue["commentDescription"] as? String
然后您可以将firestore文档转换为自定义对象,如下所示:-
func getJStoreUserFromDB()
db = Firestore.firestore()
let user = Auth.auth().currentUser
db.collection("users").document((user?.email)!).getDocument() (document, error) in
// Convert firestore document your custom object
let commentItem = CommentResponseModel(snapshot: document)
【讨论】:
感谢您的建议。但是,我正在寻找一种使用Codable
协议并将文档直接转换为对象的方法(如在Java 中,可以使用document.toObject(User.class)
。)Firebase 文档显示了类似的内容,但由于某种原因它不起作用.【参考方案2】:
在联系 firebase 团队后,我找到了我正在寻找的解决方案。事实证明我必须明确地做import FirebaseFirestoreSwift
而不是仅仅做import Firebase
。此后错误将消失。 (当然,您需要先将 pod 添加到您的 podfile 中:D)
【讨论】:
有效吗?因为我没有在导入自动完成中得到FirebaseFirestoreSwift
是的,您需要先添加pod FirebaseFirestoreSwift
。然后你可以导入:D
你能分享我上面提到的 Pod 的 GitHub 存储库吗
firebase.google.com/docs/firestore/…
很高兴我能帮上忙:D【参考方案3】:
您需要初始化您的结构,然后您可以像这样扩展 QueryDocumentSnapshot 和 QuerySnapshot:
extension QueryDocumentSnapshot
func toObject<T: Decodable>() throws -> T
let jsonData = try JSONSerialization.data(withJSONObject: data(), options: [])
let object = try JSONDecoder().decode(T.self, from: jsonData)
return object
extension QuerySnapshot
func toObject<T: Decodable>() throws -> [T]
let objects: [T] = try documents.map( try $0.toObject() )
return objects
然后,尝试通过以下方式调用 Firestore 数据库:
db.collection("users").document((user?.email)!).getDocument() (document, error) in
guard error == nil else return
guard let commentItem: [CommentResponseModel] = try? document.toObject() else return
// then continue with your code
【讨论】:
以上是关于如何在 Swift 5 中将文档转换为自定义对象?的主要内容,如果未能解决你的问题,请参考以下文章
我们可以在 javascript 中将通用对象转换为自定义对象类型吗?
将 DataSnapshot 转换为自定义结构对象 - Swift 4