Swifty Firebase API @ Ka-ching —第4部分
自动代码生成和开放源代码
这篇文章是该系列文章的第4部分,我们将探讨如何构建Firebase API的Swift扩展。
到目前为止,我们已经讨论过添加对Firebase Realtime Database API的Codable
支持,添加定义数据库结构模式的类型安全路径以及向API添加RxSwift扩展。
在本文中,我们尝试将当前讨论的所有主题包装到两个非常轻量的框架中,这些框架可以轻松地包含在您自己的项目中。 这提供了无懈可击的Codable
支持,键入安全路径和RxSwift
扩展名-您可以选择想要使用的功能。
但是,在我们开始讨论开源框架之前,让我们看一个可以使我们的生活更轻松的主题:
自动代码生成
在有关类型安全路径的文章中,我们描述了一种使用Path
类型的受约束扩展对层次结构建模的策略。 这些扩展要求键入很多样板。
诸如Sourcery和SwiftGen之类的工具由于一些很好的原因而变得流行:
- 样板很无聊,易于维护。
- 从某种形式的资产自动生成的代码将保持最新状态,因此,如果您删除或重命名资产,如果您的代码仍引用这些资产,则会立即出现编译错误。
因此,为何不必键入和维护大量的幻像类型和受约束的Path
扩展,为什么不只定义您的模式并让代码自动生成呢?
考虑以下示例架构:
{
“ configuration”:“ Configuration”,
“聊天室” : {
“ ”:{
“邮件”:{
“ ”:“消息”
},
“ name”:“ String”
}
}
}
这将定义从结构的根部到叶节点的Paths
,这些Paths
必须与代码中的模型类型名称相对应。
包裹在尖括号中的json键表示树中此刻的数据是集合的一部分。
您会注意到,没有实体定义聊天室。 出于上述架构的考虑,没有对应于聊天室的模型类型,但是您需要创建一个通往聊天室的路径才能获取该聊天室的消息。
这个概念是使用幻像类型建模的。 代码生成器将生成一个没有值的名为Chatroom
的枚举。 这意味着Chatroom
永远无法实例化,但仍可以在我们的代码中用作通用限制。
使用从以上架构生成的代码,您可以生成如下路径:
让messagesPath = Path()。chatrooms.child(“ firechat”)。messages
或者,您可以使用自动生成的便捷方法,该方法将.child(_ key:String)方法包装如下:
让messagesPath = Path()。chatroom(“ firechat”)。messages
messagesPath
变量的类型为Path.Collection
。 换句话说,是消息集合的路径。
这里提供了从上述json生成的完整代码作为示例:
导入FireSwift_Database
枚举聊天室{}
扩展路径,其中元素==根{
var configuration:Path {
返回Path.append(自身,“配置”)
}
var chatrooms:Path .Collection {
返回Path.append(自己,“聊天室”)
}
// 方便
func chatroom(_键:字符串)-> Path {
返回chatrooms.child(key)
}
}
扩展路径,其中元素==聊天室{
var讯息:Path .Collection {
返回Path.append(自身,“消息”)
}
// 方便
func message(_键:字符串)-> Path {
返回messages.child(key)
}
变量名称:Path {
返回Path.append(自身,“名称”)
}
}
生成Path
扩展的Swift脚本称为GeneratePaths.swift
。 我认为确切地探索它的作用不是很有趣-但总体而言该策略是:
- JSON结构使用单个递归类型建模:可以表示“叶”节点(示例中的具体模型类型,如
Configuration
,Message
和String
)或“分支”节点(由节点中生成的幻像类型表示)的Tree
。输出-如示例中的Chatroom
)。 - 在解码中,一些重组在子节点被处理之后发生,因为只有在解析父节点之后,我们才能知道子节点是否是集合的一部分。
- 解析后,将为每种幻像类型输出一个枚举,并且为每种幻像类型输出
Path
的扩展。 每个扩展都包含用于访问所生成树的子节点的成员。
自动代码生成的未来方向
当前策略非常基础,您可能会很快遇到当前脚本版本无法解决的问题:
- 生成的幻像类型的名称可能与代码中现有的类型名称冲突。 通过在调用脚本时为生成的幻像类型提供前缀或后缀,可以解决此问题。
- 生成的幻像类型的名称可能会相互冲突-如果将相同的名称用于结构中的单独路径元素。 将来可以通过允许您在JSON文件中描述所需的生成类型名称以及树结构来解决此问题。 我们只需要考虑一种描述这种情况的好方法。 (非常欢迎提出建议)。
- 当前,您无法为集合的集合建模(即,两个嵌套的
元素)。 当前唯一的解决方法是手动建模数据库层次结构中的任何此类部分。
非常欢迎提出改进建议,以及有关如何解决JSON格式注释问题的建议。
开源框架
先前博客文章中讨论的概念已分为两个框架:
- 仅依赖于Firebase(FireSwift-Database)的一种
- 另一个添加了RxSwift扩展(RxFireSwift-Database)
这意味着非Rx用户仍然可以从Codable
支持中受益,并且还可以使用Path
概念。
另一方面,RxSwift用户只需获取其他框架即可获得完整的表达能力。
这两个框架都构建为静态链接框架。 这是由于Firebase框架套件已经作为静态链接框架分发的事实。
通过这种方式分布框架的一个好处是,在运行时,您不必支付动态加载库的额外费用。
用法
有关使用示例,请参考每个框架的README.md
。
安装
当前唯一的安装方法是通过Carthage
如果您也对CocoaPods
支持感兴趣, CocoaPods
与我们联系,或者甚至通过创建添加CocoaPods
支持的请求请求来支持该项目! 🙂
Github
ka-ching-as / FireSwift-Database
Firebase实时数据库的扩展,可以使用“ Codable” Swift类型。 … github.com
和
ka-ching-as / RxFireSwift-Database
Firebase实时数据库的RxSwift扩展– ka-ching-as / RxFireSwift-Database github.com
关于作者
我叫Morten Bek Ditlevsen,我在丹麦Ka-ching公司(丹麦网站)工作。
在Ka-ching,我们正在为iOS构建世界一流的销售点系统。 目前,我们仅是B2B商店,但是一旦进入App Store,我们将及时通知您。 🙂
反馈
如果您对某些示例有任何疑问,评论或需要澄清,请随时提出要求!