Swift 将快照解析为模型-FirebaseUI
我目前正从Android开发人员转到Firebase的Swift开发人员 在Android中,将Firebase检索到的快照解析为对象(例如dataSnapshot.getvalue(EventModel.class))非常容易 我们如何在Swift中实现同样的目标?似乎没有这样的功能。我使用Firebase ui检索列表的对象,有一个参数“modelClass”,但没有关于如何定义该类的信息 我们必须如何定义以下对象:Swift 将快照解析为模型-FirebaseUI,swift,firebase,Swift,Firebase,我目前正从Android开发人员转到Firebase的Swift开发人员 在Android中,将Firebase检索到的快照解析为对象(例如dataSnapshot.getvalue(EventModel.class))非常容易 我们如何在Swift中实现同样的目标?似乎没有这样的功能。我使用Firebase ui检索列表的对象,有一个参数“modelClass”,但没有关于如何定义该类的信息 我们必须如何定义以下对象: 事件模型: 名称:string 描述:字符串 messages:Mes
- 事件模型:
- 名称:string
- 描述:字符串
- messages:MessageModel
- 消息模型:
- 作者:string
- 内容:字符串
亨利,这里是FirebaseUI的作者,好问题 简单的回答是,用于Firebase的Objective-C客户端对于Android/Java
snapshot.getValue(Object.class)
没有类似的功能。这是由于几个原因造成的,但本质上Java有一些Objective-C所没有的东西(在本例中,类型注释和泛型是两个相关的东西),这使得我们无法在客户机中轻松完成这项工作。通常,如果Objective-C不提供现成的功能,人们最终会构建/使用JSON对象映射器(我假设ObjectWrapper就是这样)
较长的答案是,通过使用Objective-C运行时并使用反射将接收到的字典转换为模型对象,可以实现这一点。我拼凑了一个modelClass
实现,它在FirebaseUI中是半无文档记录的,因为它只能在有限的环境中工作。请参阅下面的文档快速浏览:)
当前功能只是创建类的实例,然后直接从snapshot.value
提供的字典中填充字段(请参见实现)。这意味着属性必须与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]
或MyModelClass.self
。请查看并获取如何使用此功能的简单实现
我仍在测试我是否可以制作一个更健壮的版本,该版本可以合并到客户端库中(它可能看起来像-valueAsObject:(Class)Class
,所以你可以做一些类似MyClass*customClass=[snapshot valueAsObject:[MyClass]];
)的事情,如果真的有可能的话,我不知道,或者,如果它能看到曙光的话。我已经写了一个类似于android版本的功能。
它是一个通用解析器,允许您轻松地将快照转换为swift对象(或列表)
对于您的问题,以下代码将完成此工作:
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"
}
}
}
感谢您提供的详细信息:)如果Firebase(-UI)中有更多关于这方面的文档,那就太好了,就像在Android中一样,这是一个非常有用的功能!使用模型非常好,因为您可以保持代码的一致性,并且可以轻松地更改数据。即使显示关于哪种方法是构建自定义JSON对象包装器(使用嵌套对象)的最佳方法的信息也非常好!此外,作为旁注,是否可以在FirebaseTableViewDatasource中传递查询?对数据进行排序很有用。您可以将Firebase引用或Firebase查询(FQuery)传递给数据源进行筛选。我们还致力于支持更好的客户端过滤(排序、谓词等)和(主要取决于我的日程安排)。好的,但似乎不可能在FirebaseTableViewDataSource中传递FQQuery。您有swift中的代码示例吗?谢谢这看起来像是斯威夫特处理子类型的问题。。。Obj-C完全可以将
FQuery
传递到具有Firebase
ref的位置(Firebase
是FQuery
的子类)。实际上,我们应该使用\uu类FQuery*
,这在理论上应该可以解决问题(尽管它在其他地方显然不起作用。我们可能需要做的是为Swift提供第二组构造函数,它们使用-initWithQuery:…
)。