将 Firebase 快照投射到 Swift 3 对象

Posted

技术标签:

【中文标题】将 Firebase 快照投射到 Swift 3 对象【英文标题】:Casting Firebase Snapshot to Swift 3 object 【发布时间】:2016-12-30 17:59:55 【问题描述】:

我正在从 Firebase 数据库中检索对象,我需要将它们转换为自定义结构类对象

类:

struct Request 
    var Address: String!
    var Position: Position!
    var RequestID: String!
    var Status: String!

从我的 Firebase DB 获取快照的函数:

self.ref.child("requests").observe(.childAdded, with:  snapshot in

    //I need to cast this snapshot object to a new Request object here

    let dataChange = snapshot.value as? [String:AnyObject]

    print(dataChange)

)

我怎样才能完成这项工作?

【问题讨论】:

看看这个关于这个主题的优秀答案...***.com/a/38154998/2570590 【参考方案1】:

有几件事。 Firebase 没有对象——它是一个 JSON 结构。当您像这样获得 snapshot.value 时:

let dataChange = snapshot.value as? [String:AnyObject]

[String: AnyObject] 将数据定义为字典。

然后您可以像这样访问 dataChange 中的键:值对

let address = dataChange["address"]

let position = dataChange["position"]

您可以从那里创建新对象并在闭包中填充它们(例如将它们添加到数组中)或在对象中添加更多智能并传递字典并让对象自行填充。

以下是伪代码,但它展示了过程:

//create the object and populate it 'manually'
self.ref.child("requests").observe(.childAdded, with:  snapshot in

    let dataChange = snapshot.value as? [String:AnyObject]

    let aRequest = Request()
    aRequest.address = dataChange["address"]
    aRequest.position = dataChange["position"]
    self.requestArray.append(aRequest)
)

Class Request 

   var address = ""
   var position = ""

   func initWithDict(aDict: [String: AnyObject]) 
    self.address = aDict["address"]
    self.position = aDict["position"]
   



//let the object populate itself.
self.ref.child("requests").observe(.childAdded, with:  snapshot in

    let dataChange = snapshot.value as? [String:AnyObject]
    let aRequest = Request(initWithDict: dataChange)
    self.requestArray.append(aRequest)
)

【讨论】:

感谢您精彩的解释!然而,我遇到了一个奇怪的问题。在我执行该行时:let address = dataChange["address"]', it crashes because the value "address" is actually read as **Address**. In that case I tried: let address = dataChange["Address"]. Everything was working well until suddenly it started reading it as let address = dataChange["address"]`。为什么它不断改变 JSON 值的大小写? @RickGrimesLikesWalkerSoup 这与您的 Firebase 结构直接相关。我猜你可能有一些标记为“地址”的键和其他的“地址”——它们必须是一致的。您可以通过使用 and if let address = dataChange["address"] 技术来避免崩溃,但最终数据(键名)应该是一致的。 哈哈,这就是我最后求助的技巧。我检查了它是否为 nil,如果是,我更改大小写并再次检查。不管怎样,谢谢杰。您的解决方案有效【参考方案2】:

如果你的结构有很多字段,这样做会更容易(Swift 4+):

struct Request: Decodable 
    var Address: String
    var RequestID: String
    var Status: String


self.ref.child("requests").observe(.childAdded, with:  snapshot in
    guard let data = try? JSONSerialization.data(withJSONObject: snapshot.value as Any, options: []) else  return 
    let yourStructObject = try? JSONDecoder().decode(Request.self, from: data)

【讨论】:

以上是关于将 Firebase 快照投射到 Swift 3 对象的主要内容,如果未能解决你的问题,请参考以下文章

Swift Firebase 快照查询缺少孩子

在 Swift 3 中包含字典的 Firebase 进程子快照

Swift 3 从 Firebase 获取用户数据

Firebase:使用 swift3 访问快照子项

swift - Firebase 数据库快照检索。

使用 Swift 遍历 Firebase 中的嵌套快照子项