2017-11-23 15 views
2

Firebase DataSnapshotからデータをデコードしようとしています。そのため、JSONDecoderを使用してデコードすることができます。Swift 4のJSONDecoderをFirebase Realtime Databaseで使用できますか?

URLを使用してネットワークリクエスト(データオブジェクトを取得)でアクセスすると、このデータを正しくデコードできます。

しかし、this pageに記載されているようにobserveSingleEventを使用してFirebase APIを使用してデータを直接取得したいとします。

私はこれを行うと、結果をDataオブジェクトに変換できないように見えます。これはJSONDecoderを使用する必要があります。

DataSnapshotを使用して新しいスタイルのJSONデコードを行うことは可能ですか?どのように可能ですか?私はそれを把握していないようだ。

+0

FirebaseからデータをフェッチするときにJSONDecoderを使用しないでください。代わりに、Firebase APIを使用する必要があります。 –

答えて

2

いいえ。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 
    ] 
    } 

} 

と(toAnyObjectを使用します:あなたは非常にシンプルで理解しやすいである、しかし、この構造を使用することができます

let groceryItemRef = ref.child("items") 

groceryItemRef.setValue(groceryItem.toAnyObject()) 

フォント:https://www.raywenderlich.com/139322/firebase-tutorial-getting-started-2

+1

これは私が探していた方向だった。この方法でスナップショットを直接操作できることはわかりませんでした。私はすでにデコード可能なデータ構造を持っていたので、これを修正するのは簡単でした。また、このコードは元の要求コードよりもさらに小さくなっていました。勝つために勝つ。 – wazawoo

7

は、私が作成していますCodableFirebaseというライブラリで、Firebase用に特別に設計されたEncodersDecodersを提供しています。したがって、上記の例

:私はデータにJSONに戻すスナップショットを変換することによってJSONDecoderを使用してFirebaseスナップショットを変換しました

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) 
    } 
}) 
2

:ここ

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) 

そして、あなたが同じデータを読み込みます方法ですフォーマット。構造体は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) 
     } 
    }) 

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 
    } 
} 

詳細については、Appleドキュメントhereを参照してください。

関連する問題