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结构使用单个递归类型建模:可以表示“叶”节点(示例中的具体模型类型,如ConfigurationMessageString )或“分支”节点(由节点中生成的幻像类型表示)的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,我们将及时通知您。 🙂

反馈

如果您对某些示例有任何疑问,评论或需要澄清,请随时提出要求!