我目前正在使用Firebase从Android dev转移到Swift dev。
在Android中,将Firebase检索到的快照解析为对象非常容易(例如dataSnapshot.getvalue(EventModel.class))
我们怎样才能在Swift中实现同样的目标?似乎没有这样的功能。我使用Firebase-ui来检索列表的对象,有一个参数“modelClass”,但是没有关于如何定义该类的信息。
我们如何定义以下对象:
EventModel:
MessageModel:
有没有办法轻松定义它并在Swift中解析快照?或者我们是否必须使用自定义函数/类,如ObjectWrapper?
亲切的问候,
亨利
答案 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.m和Message.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"
}
}
}