早在 2012 年,Apple 就在 ios 5 中引入了 icloud。同时,该公司宣布开发者将可以通过多个api访问 iCloud 。起初,开发者有三个选择:
键值存储
文件存储
核心数据集成
但是,这些 API 并不完美。一个主要缺点是缺乏透明度。尤其是核心数据集成, 即使是最有经验的开发人员也会感到沮丧和困惑。当出现问题时,开发人员不知道罪魁祸首是什么或谁。这可能是他们的代码或 Apple 的问题。
CloudKit
在 WWDC 2014 上,Apple 推出了 CloudKit,这是一个全新的框架,可直接与 Apple 的 iCloud 服务器交互。该框架可与许多 PaaS (平台即服务)解决方案相媲美,例如firebase。与 Firebase 一样,Apple 提供了一个灵活的 API 和一个仪表板,让开发人员可以查看存储在 Apple iCloud 服务器上的数据。
我最喜欢 CloudKit 的地方在于 Apple 自己对该框架的承诺。据该公司称, iCloud Drive 和 iCloud Photo Library 是建立在 CloudKit 之上的。这表明 CloudKit 框架及其基础设施是健壮和可靠的。
作为开发人员,这种信任和承诺的标志很重要。过去,Apple 偶尔会发布受 bug 困扰或缺乏关键功能的 API,这仅仅是因为该公司不吃自己的狗粮。CloudKit 并非如此。这是有希望的。
你应该使用 CloudKit 吗?
键值存储和文档存储有其用途,Apple 强调 CloudKit 不会取代或弃用现有的 iCloud API。核心数据也是如此。例如,CloudKit 不提供本地存储。这意味着在没有网络连接的设备上运行的应用程序如果仅依赖于 CloudKit 将毫无用处。
Apple 还强调错误处理在使用 CloudKit 时至关重要。例如,如果保存操作失败,并且用户没有收到通知,那么她甚至可能不知道她的数据没有保存——并且丢失了。
CloudKit 是在云端存储结构化和非结构化数据的绝佳解决方案。如果您需要一个解决方案来访问多个设备上的数据,那么 CloudKit 无疑是一个值得考虑的选择。
在 2015 年的 WWDC 上,Apple 做了很少有开发者期待或希望的事情。它宣布了 CloudKit 的网络服务。这意味着 CloudKit 几乎可以在任何平台上使用,包括android和 Windows Phone。
苹果的定价也 很有竞争力 。CloudKit 入门是免费的,并且对于大多数应用程序来说仍然是免费的。同样,如果您打算将数据存储在云中,CloudKit 肯定值得考虑。
CloudKit 概念
与 Core data 苦苦挣扎的开发人员通常不熟悉框架的构建块。如果你不花时间去了解和理解 Core Data 堆栈,那么你将不可避免地遇到问题。CloudKit 也是如此。
在我们开始使用 CloudKit 的示例应用程序之前,我想花几分钟时间向您介绍 CloudKit 框架和基础架构的一些关键概念。让我们从容器、数据库和沙盒开始。
隐私和遏制
Apple 明确表示隐私是 CloudKit 的一个重要方面。首先要知道的是,每个应用程序在 iCloud 中都有自己的容器。这个概念与每个 iOS 应用程序都有自己的沙箱非常相似。但是,可以与其他应用程序共享一个容器,只要这些应用程序与同一个开发者帐户相关联。正如您可以想象的那样,这为开发人员打开了许多有趣的可能性。
一个 CloudKit 容器包含多个数据库。每个容器都有一个公共数据库,可用于存储应用程序的每个用户都可以访问的数据。除了公共数据库之外,容器还为应用程序的每个用户包含一个私有数据库。用户的私有数据库用于存储特定于该特定用户的数据。数据隔离和封装是 CloudKit 和 iCloud 基础架构的关键组件。
尽管应用程序的容器可以保存许多数据库,但从开发人员的角度来看,一个容器只保存两个数据库: 公共数据库 和 当前登录到其 iCloud 帐户的用户的私有数据库。截至 2017 年,Apple 推出了第三个数据库 shared database,使应用程序能够共享在另一个用户的私人数据库上共享的记录子集,并邀请他们为这些公开的记录做出贡献。
稍后我将详细讨论 iCloud 帐户。
记录和记录区
应用程序容器存储记录的数据库。这与传统数据库没有太大区别。乍一看,存储在 CloudKit 数据库中的记录似乎只不过是键值对字典的包装器。它们可能看起来像美化的字典,但这只是故事的一部分。
每条记录也有一个 记录类型 和一些 元数据 字段。记录的元数据会跟踪记录的创建时间、创建记录的用户、记录的最后更新日期以及更新记录的人员。
该类 CKRecord 代表了这样一个记录,并且它是一个非常强大的类。您可以存储在记录中的值不限于属性列表类型。您可以将字符串、数字、日期和数据块存储在记录中,但 CKRecord 该类还将位置数据 , CLLocation视为第一类数据类型。
您甚至可以在记录中存储支持的数据类型的数组。换句话说,字符串或数字的数组对于 CKRecord 实例来说是没有问题的。
记录在记录区中组织。记录区对相关记录进行分组。公共和私有数据库各有一个默认记录区,但如果需要,可以创建自定义记录区。记录区是一个高级主题,我们不会在本系列中详细讨论。
关系
记录之间的关系由 CKReference 类的实例管理。让我们看一个例子来更好地理解关系是如何工作的。我们将在本系列中创建的应用程序将管理许多购物清单。每个列表中可以包含零个或多个项目。这意味着每个项目都需要引用它所属的列表。
重要的是要了解该项目保留对列表的引用。虽然可以为 CKReference 列表中的项目创建实例数组,但更方便且推荐使用项目的外键,而不是列表。这也是苹果推荐的。
CloudKit 管理关系的方式相当基本,但它确实提供了一个选项,可以在删除父记录时自动删除记录的子记录。我们将在本系列的稍后部分仔细研究关系。
资产
我还想提一下 CKAsset 班级。虽然可以将数据块存储在记录中,但非结构化数据(例如图像、音频和视频)应作为 CKAsset 实例存储。一个 CKAsset 实例总是与一条记录相关联,它对应于磁盘上的一个文件。在本系列中,我们不会使用 CKAsset 该类。
验证
我相信你同意 CloudKit 看起来很吸引人。然而,有一个重要的细节我们还没有讨论:身份验证。用户通过他们的 iCloud 帐户进行身份验证。未登录 iCloud 帐户的用户无法将数据写入 iCloud。
虽然这适用于任何 iCloud API,但请记住,在这种情况下,仅依赖 CloudKit 的应用程序将无法正常工作。如果开发人员允许,用户所能做的就是访问公共数据库中的数据。
读取数据
未登录其 iCloud 帐户的用户仍然可以从公共数据库中读取数据。不用说私有数据库是不可访问的,因为 iCloud 不知道谁在使用该应用程序。
读写
登录后,用户可以读取和写入公共及其私有数据库。我已经提到苹果非常重视隐私。因此,存储在私有数据库中的记录只能由用户访问。即使是您,开发人员,也看不到用户存储在其私有数据库中的数据。这是 Apple 管理应用程序后端的缺点,但对用户来说无疑是一个胜利。
购物清单
我们即将构建的应用程序将管理您的购物清单。每个购物清单都有一个名称和零个或多个项目。构建购物清单应用程序后,您应该会觉得在自己的项目中使用 CloudKit 框架很舒服。
先决条件
对于本教程,我将使用 Xcode 9 和 swift 4。如果您使用的是旧版本的 Xcode,请记住您使用的是不同版本的 Swift 编程语言。这意味着您将需要更新项目的源代码以满足编译器的要求。这些变化大多很小,但重要的是要意识到这一点。
因为 CloudKit 是一个高级主题,所以我假设您熟悉 Xcode 和 Swift 编程语言。如果您是 iOS 开发新手,那么我建议您先阅读入门教程或参加我们的 Swift 开发课程之一:
如果您不熟悉 iOS 开发或 Swift 语言,请务必查看这些内容。
项目设置
是时候开始编写一些代码了。启动 Xcode 并基于 Single View Application 模板创建一个新项目。
为您的项目 命名 和 组织标识符。生成的包标识符将用于创建应用程序默认容器的标识符。该标识符在开发人员帐户之间必须是唯一的,因为它们共享一个全局命名空间。因此,遵循 Apple 的建议并使用 反向域名表示法很重要。
启用 iCloud
下一步是启用 iCloud 和 CloudKit。 在左侧的Project Navigator中选择项目, 然后从目标列表中为您的应用程序选择目标。打开 常规 选项卡并将 团队设置 为正确的团队。为避免在下一步出现任何问题,请验证您的开发者帐户是否具有创建App ID所需的权限 。
接下来,打开 顶部 的功能选项卡并将iCloud的开关设置为 打开。Xcode 将需要一点时间来 代表您创建一个App ID 。它还将向 App ID 添加必要的权利。如果这不起作用,请确保团队设置正确并且您拥有创建 App ID 所需的权限。
启用 CloudKit 就像选中标记为CloudKit的复选框一样简单 。默认情况下,您的应用程序将为您的应用程序使用默认容器。当您启用 CloudKit 时,会自动为您创建此容器。
如果您的应用程序需要访问不同的容器或多个容器,请选中标有“ 指定自定义容器”的复选框 并选中您的应用程序需要访问的容器。
您可能已经注意到 Xcode 已自动将您的目标链接到 CloudKit 框架。这意味着您已准备好开始在您的应用程序中使用 CloudKit。
弄湿你的脚
在本系列的下一个教程中,我们将添加添加、编辑和删除购物清单的功能。然而,为了完成本教程,我想通过向您展示如何与 CloudKit API 交互来让您体验一下。我们要做的就是获取当前登录用户的记录。
打开 ViewController.swift 并在顶部添加一个 import 语句来导入 CloudKit 框架。
import UIKit import CloudKit
要获取用户记录,我们首先需要获取记录的标识符。让我们看看这是如何工作的。我创建了一个辅助方法 , fetchUserRecordID以包含用于获取用户记录标识符的逻辑。我们在视图控制器的方法中调用此 viewDidLoad 方法。
override func viewDidLoad() { super.viewDidLoad() // Fetch User Record ID fetchUserRecordID() }
的实现 fetchUserRecordID 比 viewDidLoad. defaultContainer 我们首先通过调用类来获取对 应用程序默认容器的引用 CKContainer 。然后我们调用 fetchUserRecordIDWithCompletionHandler(_:) . defaultContainer这个方法接受一个闭包作为它的唯一参数。
private func fetchUserRecordID() { // Fetch Default Container let defaultContainer = CKContainer.default() // Fetch User Record defaultContainer.fetchUserRecordID { (recordID, error) -> Void in if let responseError = error { print(responseError) } else if let userRecordID = recordID { DispatchQueue.main.sync { self.fetchUserRecord(recordID: userRecordID) } } } }
闭包接受两个参数:一个可选 CKRecordID 实例和一个可选 NSError 实例。如果 error 是 nil,我们安全地打开包装 recordID。
重要的是要强调闭包将在后台线程上调用。这意味着在 CloudKit 调用的闭包中更新应用程序的用户界面时需要小心。fetchUserRecordID例如,我在主线程上显式 调用 fetchUserRecord(_:) 。
在 fetchUserRecord(_:)中,我们通过告诉 CloudKit 我们感兴趣的记录来获取用户记录。请注意,我们调用 fetchRecordWithID(_:completionHandler:) 了 privateDatabase 对象,该对象的属性 defaultContainer 。
该方法接受一个 CKRecordID 实例和一个完成处理程序。后者接受一个可选 CKRecord 实例和一个 NSError 实例。如果我们成功获取了用户记录,我们将它打印到 Xcode 的控制台。
private func fetchUserRecord(recordID: CKRecordID) { // Fetch Default Container let defaultContainer = CKContainer.default() // Fetch Private Database let privateDatabase = defaultContainer.privateCloudDatabase // Fetch User Record privateDatabase.fetch(withRecordID: recordID) { (record, error) -> Void in if let responseError = error { print(responseError) } else if let userRecord = record { print(userRecord) } } }
当您在 Xcode 中运行应用程序时,您将在控制台中看到类似于以下内容的内容:
这应该让您对 CloudKit 框架有所了解。它的现代 API 直观且易于使用。在下一个教程中,我们将深入挖掘 CloudKit API 的可能性。
您可以在GitHub (tag #introduction)上克隆完整的示例项目 。
结论
您现在应该对 CloudKit 框架的基础有了正确的了解。本系列的其余部分将重点关注构建购物清单应用程序。在下一个教程中,我们将从添加添加、编辑和删除购物清单的功能开始。
- 隐私和遏制
- 记录和记录区
- 关系
- 资产
- 验证
- 读取数据
- 读写
- 先决条件
- 项目设置
- 启用 iCloud
- 弄湿你的脚