2017-11-23 1 views
2

Firebase DataSnapshot에서 데이터를 디코딩하려고하므로 JSONDecoder를 사용하여 디코딩 할 수 있습니다.Swift 4의 JSONDecoder를 Firebase Realtime Database와 함께 사용할 수 있습니까?

URL을 사용하여 네트워크 요청 (데이터 개체 얻기)에 액세스 할 때이 데이터를 잘 디코딩 할 수 있습니다.

그러나 this page에 설명 된대로 observeSingleEvent를 사용하여 Firebase API를 사용하여 직접 데이터를 가져 오려고합니다.

그러나이 작업을 수행 할 때 결과를 JSONDecoder를 사용해야하는 Data 개체로 변환 할 수 없습니다.

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

내가 만든 Firebase 용으로 특별히 설계된 이라는 라이브러리는 EncodersDecoders을 제공합니다. 따라서 위의 예를 들어

: 나는 데이터에서 JSON에 다시 스냅 샷을 변환하여 JSONDecoder를를 사용하여 중포 기지 스냅 샷을 변환 한

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을 참조하십시오.

관련 문제