Firebase将快照值转换为对象

Dar*_*ong 14 firebase swift firebase-realtime-database

所以我有一个postDictas [String: AnyObject],我有一个模型类Post.

是否有一种快速转换postDictPost对象数组的方法,以便在将单元格出列时,它将是:

cell.textLabel.text = posts[indexPath.item].author

import UIKit
import Firebase

class ViewController: UIViewController {

var posts = [Post]()

override func viewDidLoad() {
    super.viewDidLoad()

    let ref = FIRDatabase.database().reference().child("posts").queryLimitedToFirst(5)

    ref.observeEventType(FIRDataEventType.ChildAdded, withBlock: { (snapshot) in
        let postDict = snapshot.value as! [String : AnyObject]

        print(postDict)          

        //convert postDict to array of Post objects
    })
  }
}

class Post: NSObject {
    var author: String = ""
    var body: String = ""
    var imageURL: String = ""
    var uid: String = ""
}
Run Code Online (Sandbox Code Playgroud)

这是打印出postDict时的输出:

在此输入图像描述

Cal*_*lam 21

尝试使用我在下面创建的类,协议和扩展,它将为您节省大量时间来尝试将快照映射到对象.

//
//  FIRDataObject.swift
//
//  Created by Callam Poynter on 24/06/2016.
//

import Firebase

class FIRDataObject: NSObject {

    let snapshot: FIRDataSnapshot
    var key: String { return snapshot.key }
    var ref: FIRDatabaseReference { return snapshot.ref }

    required init(snapshot: FIRDataSnapshot) {

        self.snapshot = snapshot

        super.init()

        for child in in snapshot.children.allObjects as? [FIRDataSnapshot] ?? [] {
            if respondsToSelector(Selector(child.key)) {
                setValue(child.value, forKey: child.key)
            }
        }
    }
}

protocol FIRDatabaseReferenceable {
    var ref: FIRDatabaseReference { get }
}

extension FIRDatabaseReferenceable {
    var ref: FIRDatabaseReference {
        return FIRDatabase.database().reference()
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,您可以创建一个继承FIRDataObject类的模型,并可以使用FIRDataSnapshot进行初始化.然后将FIRDatabaseReferenceable协议添加到ViewController以访问您的基本引用.

import Firebase
import UIKit

class ViewController: UIViewController, FIRDatabaseReferenceable {

    var posts: [Post] = []

    override func viewDidLoad() {

        super.viewDidLoad()

        ref.child("posts").observeEventType(.ChildAdded, withBlock: {
            self.posts.append(Post(snapshot: $0))
        })
    }
}

class Post: FIRDataObject {

    var author: String = ""
    var body: String = ""
    var imageURL: String = ""
}
Run Code Online (Sandbox Code Playgroud)

Swift 3的更新

class FIRDataObject: NSObject {

    let snapshot: FIRDataSnapshot
    var key: String { return snapshot.key }
    var ref: FIRDatabaseReference { return snapshot.ref }

    required init(snapshot: FIRDataSnapshot) {

        self.snapshot = snapshot

        super.init()

        for child in snapshot.children.allObjects as? [FIRDataSnapshot] ?? [] {
            if responds(to: Selector(child.key)) {
                setValue(child.value, forKey: child.key)
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 好的!您将如何处理嵌套对象? (2认同)
  • @callam,您应该将此代码作为要点放在 GitHub 中,以便可以跟踪更新。我在网上找到了您的代码的多个版本,并试图使它们保持一致 (2认同)

Dar*_*ong 8

感谢上面的所有评论和提示.他们肯定有帮助.所以我使用setValuesForKeysWithDictionary的方法.它将他们变成了一系列帖子.

import UIKit
import Firebase
class ViewController: UIViewController {

var posts = [Post]()

override func viewDidLoad() {
    super.viewDidLoad()

    let ref = FIRDatabase.database().reference().child("posts").queryLimitedToFirst(3)

    ref.observeEventType(.Value, withBlock: { snapshot in
        print(snapshot.value)
        self.posts = []
        if let snapshots = snapshot.children.allObjects as? [FIRDataSnapshot] {
            for snap in snapshots {
                if let postDict = snap.value as? Dictionary<String, AnyObject> {
                    let post = Post()
                    post.setValuesForKeysWithDictionary(postDict)
                    self.posts.append(post)
                }
            }
        }
        print("post 0: \(self.posts[0].body)")
        print("post 1: \(self.posts[1].body)")
        print("post 2: \(self.posts[2].body)")
      })
   }
}

class Post: NSObject {
    var author: String = ""
    var body: String = ""
    var imageURL: String = ""
    var uid: String = ""
}
Run Code Online (Sandbox Code Playgroud)


Noo*_*ass 8

我写了一个名为CodableFirebase的小框架,可以帮助Codable在swift 4中使用Firebase实时数据库.所以在你的情况下,你需要使你的Post模型符合Codable:

class Post: NSObject, Codable {
    var author: String = ""
    var body: String = ""
    var imageURL: String = ""
    var uid: String = ""
}
Run Code Online (Sandbox Code Playgroud)

然后你可以使用库来解析对象:

import CodableFirebase

ref.observeEventType(.?hildAdded, withBlock: { (snapshot) in
    guard let value = snapshot.value else { return }
    do {
        let posts = try FirebaseDecoder().decode([Post].self, from: value)
        print(posts)
    } catch let error {
        print(error)
    }
})
Run Code Online (Sandbox Code Playgroud)

就是这样:)我认为这是最短最优雅的方式.