waz*_*woo 11 json json-deserialization swift firebase-realtime-database
我正在尝试解码Firebase DataSnapshot中的数据,以便可以使用JSONDecoder对其进行解码.
当我使用URL通过网络请求访问它(获取Data对象)时,我可以正确解码此数据.
不过,我想用火力地堡API直接获取数据,使用observeSingleEvent上描述这个页面.
但是,当我这样做时,我似乎无法将结果转换为Data对象,我需要使用JSONDecoder.
是否可以使用DataSnapshot进行新的JSON解码?这怎么可能?我似乎无法弄明白.
Noo*_*ass 21
我创建了一个名为库CodableFirebase,提供Encoders与Decoders被用于火力地堡设计的.
所以对于上面的例子:
import Firebase
import CodableFirebase
let item: GroceryItem = // here you will create an instance of GroceryItem
let data = try! FirebaseEncoder().encode(item)
Database.database().reference().child("pathToGraceryItem").setValue(data)
Run Code Online (Sandbox Code Playgroud)
以下是您将如何阅读相同的数据:
Database.database().reference().child("pathToGraceryItem").observeSingleEvent(of: .value, with: { (snapshot) in
guard let value = snapshot.value else { return }
do {
let item = try FirebaseDecoder().decode(GroceryItem.self, from: value)
print(item)
} catch let error {
print(error)
}
})
Run Code Online (Sandbox Code Playgroud)
我通过将快照转换回数据格式的JSON,使用JSONDecoder转换了Firebase快照.您的结构需要符合Decodable或Codable.我用SwiftyJSON完成了这个,但是这个例子使用的是JSONSerialization,它仍然有效.
JSONSnapshotPotatoes {
"name": "Potatoes",
"price": 5,
}
JSONSnapshotChicken {
"name": "Chicken",
"price": 10,
"onSale": true
}
struct GroceryItem: Decodable {
var name: String
var price: Double
var onSale: Bool? //Use optionals for keys that may or may not exist
}
Database.database().reference().child("grocery_item").observeSingleEvent(of: .value, with: { (snapshot) in
guard let value = snapshot.value as? [String: Any] else { return }
do {
let jsonData = try JSONSerialization.data(withJSONObject: value, options: [])
let groceryItem = try JSONDecoder().decode(GroceryItem.self, from: jsonData)
print(groceryItem)
} catch let error {
print(error)
}
})
Run Code Online (Sandbox Code Playgroud)
请注意,如果您的JSON密钥与您的Decodable结构不同.你需要使用CodingKeys.例:
JSONSnapshotSpinach {
"title": "Spinach",
"price": 10,
"onSale": true
}
struct GroceryItem: Decodable {
var name: String
var price: Double
var onSale: Bool?
enum CodingKeys: String, CodingKey {
case name = "title"
case price
case onSale
}
}
Run Code Online (Sandbox Code Playgroud)
您可以在此处使用Apple Docs找到有关此内容的更多信息.
不可以。Firebase 返回无法解码的 FIRDataSnapshot。但是,您可以使用这种结构,它非常简单且易于理解:
struct GroceryItem {
let key: String
let name: String
let addedByUser: String
let ref: FIRDatabaseReference?
var completed: Bool
init(name: String, addedByUser: String, completed: Bool, key: String = "") {
self.key = key
self.name = name
self.addedByUser = addedByUser
self.completed = completed
self.ref = nil
}
init(snapshot: FIRDataSnapshot) {
key = snapshot.key
let snapshotValue = snapshot.value as! [String: AnyObject]
name = snapshotValue["name"] as! String
addedByUser = snapshotValue["addedByUser"] as! String
completed = snapshotValue["completed"] as! Bool
ref = snapshot.ref
}
func toAnyObject() -> Any {
return [
"name": name,
"addedByUser": addedByUser,
"completed": completed
]
}
}
Run Code Online (Sandbox Code Playgroud)
并使用 toAnyObject() 保存您的项目:
let groceryItemRef = ref.child("items")
groceryItemRef.setValue(groceryItem.toAnyObject())
Run Code Online (Sandbox Code Playgroud)
来源:https : //www.raywenderlich.com/139322/firebase-tutorial-getting-started-2
| 归档时间: |
|
| 查看次数: |
3896 次 |
| 最近记录: |