362d24923620945c5d5a12b6a193dc89
使用 CloudKit 控制台构建更好的应用

作者:sing_crystal,博客:http://www.jianshu.com/u/7a2d2cc38444

引言

自 CloudKit 首次在 iOS 8 发布以来,苹果公司每年都会推出不少更新。CloudKit 为开发者提供了后端服务,让开发者专注于 App 前端的开发,节省开发者的成本。

本文为你介绍如何借助全新的 CloudKit 控制台开发更优秀的 App。

这次,苹果公司彻底整修了 CloudKit 控制台,新功能贯穿整个开发周期:开发、测试、操作、支持 CloudKit 服务等等,获取数据变动记录,修改分享关系,获取实时的服务器日志,包括所有用户的事件,甚至是推送通知,更方便进行代码调试和为用户提供技术支持。

Baas - Backend as a Service

国内目前比较出名的 BaaS 服务商是 LeanCloud

Parse 虽然在 2017 年 1 月 28 日停止了服务,不过很多公司提供了 Parse 托管服务,例如:SashiDo.ioQurskyBack4App

苹果借助 CloudKit进军 Baas 领域,还推出了 CloudKit JS 框架,借助该框架,开发的 web 应用可以获取服务器上的数据。

例子

苹果自己的产品:Photos, iCloud Drive, Notes, News, 和 Safari 等。这些 App 能够多终端实时同步数据。当然了,也可以只在某个设备中存储,不进行多终端同步,需要额外进行设置。

Bear 的多终端实时同步技术,使用的就是 CloudKit,将用户的数据存储在 Private Database里,属于 Pro 付费功能,如果你的 iCloud 5G 免费空间已经用完,购买了 Bear 的该功能,也无法实时同步,不过数据不会丢失,会被存储在本地。也就是说,Bear 有自己的本地数据持久化方案,但同时,也支持 CloudKit 存储数据以及多终端实时同步功能。

小结

CloudKit 使用用户的 iCloud 存储空间,也就是说,私有数据是存储在用户的 iCloud 中,占用用户的 iCloud 存储空间额度。而对于公共空间,每个 App 的免费空间和额度很多,足够开发者使用了。CloudKit 费用计算器,可以计算 App 的费用。能为开发者节省不少开支。

在用户隐私和数据安全方面无需开发者担心,数据都存储在 iCloud 上,有苹果罩着呢。不过开发者无法看到用户的私有数据(Private Database),只能看到共享的(Shared Database)和公开的(Public Database)数据。

Cloudkit 的最大的优势就是够在苹果所有的系统上使用,多终端数据同步。

更新 CloudKit 控制台的初心

  • 在 App 开发的整个生命周期中都提供了所需的工具。
  • 能够在控制台直接查看、体验所有的 API。
  • 能够在控制台直接查看所有用户和系统的事件。
  • 更好的理解集合行为(aggregate behavior)以及背后的通信机制。

接下来,在演示控制台的操作之前,先介绍以下两个方面,之后再进行演示:

  1. 快速浏览一下 CloudKit 的一些核心概念。
  2. 展示一个基于 CloudKit 的示例 iOS App:Todo List App,以便于接下来演示如何使用控制台进行测试和开发。

CloudKit 核心概念

上图是 CloudKit 结构化数据关系图,为开发者提供了面向对象的、海量的、无需创建数据表结构即存即用的存储能力。

下表是关系型数据库、MongoDB 和 LeanCloud 、CloudKit 的对应术语:

RDBMS MongoDB LeanCloud CloudKit
Database Database Application Container
Table Collection Class Zone
Row Document Object Record
Index Index Index Index
JOIN Embedded, Reference Embedded Object, Pointer Reference

从上面的表格中科院发现,CloudKit 的 Environment 和 Database,没有出现在对比表格中,会在下面解释。

Record

键值对形式存储一条 Record,值的类型有:String,Int,Double,Asset(二进制文件)。每条 Record,都有自己的 Zone。

Zone

Zone 里有很多 Record。CloudKit 有默认的 Zone,如果不够,也可以创建更多的 Zone。每个 Zone,都有自己的 Database。

Database

Cloudkit 提供了 3 种类型的 Database,各自的数据查看权限不同,分别为:Private Database(私有数据库),Shared Database(共享数据库) 和 Public Database(公开数据库)。

每个用户都有自己的私有数据库,该数据库中的数据只有用户自己可以查看,其他人包括开发者也没有权限查看。

去年苹果公司推出了 CloudKit Sharing 功能,iOS 自带的 App:便签 App 中,可以分享某条便签给其他人,就是使用了该功能。被分享的数据就存储在共享数据库中。

最后是公共数据库,每个人都可以在该数据库中进行读写。

看到这里可能会有疑问,如果我看不到私有数据库里的数据,那么如何开发?如何调试?如何解决 bug 呢?

实际上,开发的时候,可以在设备的 iCloud 上登陆自己的苹果开发者账号,这样就可以在控制台中看到自己的数据了。开发者环境还是生产环境,都可以看到自己开发者账号的数据。就是说,登陆 CloudKit 控制台的账号,要和测试设备中的 iCloud 账号一致才行。

环境和数据架构

以上所有的数据和数据库,都在某个环境(Environment)中:Development(开发环境) 和 Production(生产环境)。在开发的时候,使用开发环境,定义数据模式、Record 的类型,要存储的数据的类型,以及对应的 index,完成数据库架构(Schema)。

App 上架后,使用的是生产环境。所以记得将开发环境部署到生产环境里。

在生产环境的中,用户们有各自的的私有数据库、共享数据库和一个公开数据库,完全和开发环境隔离的,你在开发环境中做的操作,不会影响生产环境,除非你手动将新的数据模型部署到生产环境中。

Container

这算是最高层级的容器了,一个 App 对应一个 Container。不过我谷歌了一下,如果你想让多个 App 都访问同一个 Container,也是可行的(尚未实测)。想让一个 App 访问多个 Container,也可行(尚未实测)!所以,具体看你需求了。一般简单的小 App,用一个 Container 就绰绰有余了。

示例:Todo List App

Data model 数据建模

从上图中可以看出,该 App 的数据模型相对简单,用户可以创建代办清单,每个清单中可以创建要代办的事项(Item)。要用 CloudKit,Record 是必须的基本要素。在这里,创建一个名为 List 的 Record。每条 List Record 都有对应的 Items,从属关系为 Reference。

同时,还希望该 App 可以将每个代办清单分享给其他人,这里使用 CloudKit Sharing 接口。可以定义谁可以看这条记录,他们的读写权限是什么。如果想了解更多关于 CloudKit Sharing 的知识点,请参考 WWDC 2016 的 What's New with CloudKit

获取数据变更的 API

下面说一下如何使用 API、如何和服务器进行通信。

简单说一下该 App 的需求:

  1. 用户在 iPhone 上创建代办清单时,该用户的其他安装该 App 的设备也能同步信息;
  2. 如果用户将某条数据在某些人之间进行了分享,其中一人编辑后,能看到编辑后的信息;
  3. 使用 CoreData 进行本地的数据持久化,将所有的数据本地存储,以便能快速读写,在没有网络时也能使用该 App;
  4. 每次数据有了变动,且在有网的情况下,这些数据可以返回到服务器上。

推送变动通知 - CKDatabaseSubscription

在服务器上为用户的私有数据库创建 CKDatabaseSubscription,只要私有数据库的数据发生了改变,服务器就给用户的所有设备推送通知。由于我们使用了分享功能,所以还需要订阅共享数据库中的数据变动。只要服务器上的数据有了变动,就会推送通知。

  • CKDatabaseSubscription (私有数据库)
  • CKDatabaseSubscription (共享数据库)

获取变动信息 - CKFetchDatabaseChangesOperation

通过上一步操作,目前设备能收到变动通知了,那么收到变动通知后,我们得需要知道具体是哪些数据发生了变化,这就需要用到 CKFetchDatabaseChangesOperation。需要知道是哪些数据库以及数据库中的哪些 Zone 发生了数据变动:

  • CKFetchDatabaseChangesOperation (查询数据库中的数据变动)
  • CKFetchRecordZoneChangesOperation (查询 Zone 中的数据变动)

如果想了解更多信息,请参考 WWDC 2016 的 CloudKit Best Practices。由于该操作太常用了,还专门在文档中添加了一节:Maintaining a Local Cache of CloudKit Records,提供了流程介绍和代码示例。

Demo - 在 CloudKit 控制台获取数据变更信息

之前获取数据变动的操作(也就是上面刚刚讲过的这个点),只能通过代码实现,现在也能通过控制台来查看了。现在,开始体验大整修后的控制台吧~

控制台首页

在首页,可以看到:

  1. 自己所属的开发团队(可以同时属于多个开发团队);
  2. 对于每个开发团队,可以看到正在开发的项目,也就是 Container。之前提及过,一般情况下,一个 App 对应一个 Container。
  3. 能看出哪些 Container 处于开发环境,哪些 Container 已经部署到了生产环境。
  4. 搜索框,可以过滤检索团队和项目。

点击该 App 的 Container 后可以看到两个分类:开发环境和生产环境,点击生产环境的 Data 模块后,进入名为 Zones 的 Tab 页。

按上图所示,选择私有数据库(也可以选择其他的数据库),勾选 Fetch zone changes since... 选项,这样就可以查看变动了。

如果这里你查不到数据,看一下设备的 iCloud 账号是不是你的开发者账号,如果是同一个账号,却查不到变化。那么可以点击名为 RECORDS 的 Tab 页,如下图:

这里不可用,说明你未支持查询变动,检查一下上面刚刚提及的两个获取数据变更的 API 是否已经实现。

如果操作无误,差点查询变更,会出现如下图所示的结果(需要你先在设备上创建或者变更一条数据,才能在控制台中看到):

点击之后,可以看到:

尝试着点击列出的 Record,在右边弹出的详细信息框中,尝试改一些东西,设备上回立即同步变更。

Demo - 在 CloudKit 控制台获取订阅和推送通知

如上图所示,这是查看订阅(subscription)的 Tab 页。

服务器的事件日志

上面又是查询数据变更(fetch changes),又是推送通知(push notification),还有订阅,还要设计多个设备和平台。要是又一个地方,可以看到这些所有的事件就好了,所以,这次控制台新增了事件日志功能(Log Event)。

如上图所示,可以查看所有的日志记录。

top Created with Sketch.