将快照解析为模型 - FirebaseUI

时间:2015-11-14 16:49:14

标签: swift firebase

我目前正在使用Firebase从Android dev转移到Swift dev。

在Android中,将Firebase检索到的快照解析为对象非常容易(例如dataSnapshot.getvalue(EventModel.class))

我们怎样才能在Swift中实现同样的目标?似乎没有这样的功能。我使用Firebase-ui来检索列表的对象,有一个参数“modelClass”,但是没有关于如何定义该类的信息。

我们如何定义以下对象:

  • EventModel:

    • name:string
    • description:string
    • 消息:MessageModel
  • MessageModel:

    • 作者:string
    • content:string

有没有办法轻松定义它并在Swift中解析快照?或者我们是否必须使用自定义函数/类,如ObjectWrapper?

亲切的问候,

亨利

2 个答案:

答案 0 :(得分:4)

FirebaseUI的作者,好问题!

简短的回答是,Firebase的Objective-C客户端没有Android / Java snapshot.getValue(Object.class)的类似功能。这是由于几个原因,但基本上Java有几个Objective-C没有的东西(在这种情况下键入注释和泛型是两个相关的),这阻止我们在客户端中轻松地这样做。通常,人们最终建立/使用JSON< - >对象映射器(我假设是ObjectWrapper),因为Objective-C没有提供开箱即用的功能。

更长的答案是,通过使用Objective-C运行时并使用反射将接收到的字典转换为模型对象,可以实现排序。我在FirebaseUI中一起编写了一个modelClass实现,该实现是半文档的,因为它仅适用于有限的情况。请参阅下面的文档快速传递:)

当前功能只是创建一个类的实例,然后直接从snapshot.value提供的字典填充字段(请参阅实现here)。这意味着属性必须与Firebase中的键完全匹配。 这也意味着它需要从Firebase接收一个词典 - 它不会自动转换字符串,数字,布尔值或数组。这也意味着嵌套对象不太可能工作,鉴于Objective-C没有仿制药(至少不是主流的Obj-C)。具体来说,我们目前仅支持具有原始类型值的单级Javascript对象。

如果您在Firebase中有一个JSON对象,请执行以下操作:

{
  message: {
    name: String,
    text: String
  }
}

你的Objective-C(或Swift)类看起来像:

// Obj-C
@interface MyMessageClass : NSObject

@property (nonatomic) NSString *name;
@property (nonatomic) NSString *text;

@end

// Swift
class MyMessageClass {

  let name: String!
  let text: String!

}

然后,您可以使用构造函数中modelClass:(Class)class[MyModelClass class]传递的MyModelClass.self属性。请查看ViewController.mMessage.h,了解如何使用此功能的简单实现。

我还在测试我可以制作一个可以合并到客户端库中的更强大的版本(它可能看起来像-valueAsObject:(Class)class所以你可以做MyClass *customClass = [snapshot valueAsObject:[MyClass class]];之类的事情)如果它真的有可能,或者它是否能看到光明之日的话,那就说出来了。

答案 1 :(得分:1)

我写了一个library,其功能与android版本相似。 它是一个通用解析器,允许您轻松地将快照转换为快速对象(或列表)。

对于您的问题,以下代码可以完成这项工作:

func main(){
    let model=SnapshotParser().parse(snap: Snapshot, type: EventModel.self)
}

class EventModel: ParsableObject {
    var name:String?=nil
    var description:String?=nil
    var messages:[MessageModel]?=nil

    required init(){}

    func bindProperties(binder: SnapshotParser.Binder) {
        binder.bindField(name: "name", field: &name)
        binder.bindField(name: "description", field: &description)
        binder.bindList(name: "messages", list: &messages)
    }
}
class MessageModel: ParsableSnapshot {
    var id: String?
    var author:String?=nil
    var content:String?=nil

    required init(){}

    func bindProperties(binder: SnapshotParser.Binder) {
        binder.bindField(name: "id", field: &id)
        binder.bindField(name: "author", field: &author)
        binder.bindField(name: "content", field: &content)
    }
}

json会是这样的:

    "eventModel":{
        "name":"bob",
        "description":"this is bob",
        "messages":{
            "id1":{
                "author":"alice",
                "content":"long text"
            },
            "id2":{
                "author":"alice",
                "content":"long text"
            }
        }
    }