SwiftyCloudKit
SwiftyCloudKit 是 Cloud Kit 之上的一层薄层,它使得将云支持集成到 iOS 应用程序中变得容易。
示例
要运行示例项目,克隆仓库,并在 Example 目录中运行 pod install
。强烈建议在示例项目中完成教程。
要求
- Swift 4.2 (使用 Swift 4.0 的预 0.1.5)
- iOS: 10.0+
安装
SwiftyCloudKit 通过 CocoaPods 提供。要安装它,只需将以下行添加到您的 Podfile 中
pod 'SwiftyCloudKit'
使用
SwiftyCloudKit分为三个子模块:CloudKitFetcher、CloudKitHandler和CloudKitSubscriber。注意:该库支持离线功能。如果将offlineSupport
设置为true,并且在网络连接不可用的情况下,库会临时将记录存储在本地,并在稍后上传。
CloudKitFetcher
CloudKitFetcher从iCloud获取记录。请记住,首先在CloudKit仪表板设置一个记录类型。该协议要求您实现四个变量,以定义如何执行获取操作(有关这些参数的更多信息,请参阅文档或示例项目)。
var database: CKDatabase
var query: CKQuery?
var interval: Int
var cursor: CKQueryOperation.Cursor?
var zoneID: CKRecordZone.ID
var desiredKeys: [String]?
然后,只需在例如viewDidAppear中调用获取函数以获取记录。
fetch(withCompletionHandler: { (records, error) in
// Do something with the fetched records.
})
CloudKitHandler
CloudKitHandler允许您在单个操作中上传和删除多个CloudKit记录。您可以指定操作的优先级,并针对每个记录获取操作进度的回调。如果上传或删除操作因为iCloud错误而失败,则在完成处理程序中包含的错误将是CKError。如果操作因为库未能检测到网络连接而失败(无法本地保存或删除),则将返回LocalStorageError。
upload(records: [CKRecord], withPriority priority: QualityOfService, perRecordProgress: ((CKRecord, Double) -> Void)?, andCompletionHandler completionHandler: (([CKRecord]?, Error?) -> Void)?)
func delete(records: [CKRecord], withPriority priority: QualityOfService, perRecordProgress: ((CKRecord, Double) -> Void)?, andCompletionHandler completionHandler: (([CKRecord.ID]?, Error?) -> Void)?)
示例:
let record = CKRecord(recordType: MyRecordType)
record.set(string: "Hello World", key: MyStringKey)
upload(records: [record], withPriority: .userInitiated, perRecordProgress: nil) { (uploadedRecords, error) in
// Do something with the uploaded record
})
delete(records: [record], withPriority: .userInitiated, perRecordProgress: nil) { (deletedRecordIDs, error) in
// Do something when the record is deleted
})
访问和设置记录值
为CloudKit支持的所有类型都存在辅助函数。因此,您可以使用辅助函数获取和设置字符串、引用、数据、资产、整型、双精度浮点型、位置、日期、这些类型的列表,以及使用辅助函数获取图像和视频。如果记录中存储了一个图像,在请求图像时会检索到可选的UIImage,对于视频,您将收到指向临时本地文件的可选URL,该文件可以用在AVPlayer中。这样您就不需要处理转换。注意:因为视频作为缓存存储在本地,所以需要定期清理缓存。在AppDelegate中调用deleteLocalVideos()
,例如在applicationWillTerminate(_ application: UIApplication)
中,以删除它们。如果您想删除某些视频,请使用文件管理器(视频存储在文档文件夹中,文件名为模板video_recordName_key.mov)。
要获取值,请使用value(_ key: String)
。例如。
let myString = record.string(MyStringKey)
要设置值,请使用set(value: Value, key: String)
。例如。
record.set(string: "Hello World", key: MyStringKey)
CloudKitSubscriber
当有多个单元需要对同一数据进行读写访问时,订阅非常有用。例如,一个允许多个用户协作编辑电子表格的应用程序。当新数据附加、数据删除和数据修改时,订阅会触发通知。示例项目包含有关此处的演示(请注意,iOS 模拟器不能发送这些通知,只能接收,因此请在两个 iOS 设备之间进行测试)。
订阅的前提条件包括
- 在 info.plist 中将远程通知添加到 UIBackgroundModes
- 在应用代理中注册远程通知,并在收到推送通知时在应用程序周围发布通知,方法如下
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
application.registerForRemoteNotifications()
return true
}
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
let ckqn = CKQueryNotification(fromRemoteNotificationDictionary: userInfo as! [String:NSObject])
let notification = Notification(name: NSNotification.Name(rawValue: CloudKitNotifications.NotificationReceived),
object: self,
userInfo: [CloudKitNotifications.NotificationKey: ckqn])
NotificationCenter.default.post(notification)
}
下一步是遵守协议
var subscription: CKQuerySubscription
func handleSubscriptionNotification(ckqn: CKQueryNotification) {}
最后一步是订阅和取消订阅更新。这是必要的,因为订阅相当昂贵
// Call in e.g. viewDidAppear
subscribe(_ completionHandler: ((CKError?) -> Void)?)
// Call in e.g. viewDidDisappear
unsubscribe(_ completionHandler: ((CKError?) -> Void)?)
用户数据管理
该库包含辅助函数,使用户管理他们的数据变得很容易。
检索所有数据副本
retrieveRecords(containerRecordTypes: [CKContainer: [String]]) -> [CKContainer: [CKRecord]]
删除
以下方法会删除给定容器中用户创建的所有私有和公开数据。
erasePrivateData(inContainers containers: [CKContainer], completionHandler: @escaping (Error?) -> Void)
eraseUserCreatedPublicData(containerRecordTypes: [CKContainer: [String]], completionHandler: @escaping (Error?) -> Void)
限制
为了限制数据库并解除限制,请使用以下方法
restrict(container: CKContainer, apiToken: String, webToken: String, environment: Environment, completionHandler: @escaping (Error?) -> Void)
unrestrict(container: CKContainer, apiToken: String, webToken: String, environment: Environment, completionHandler: @escaping (Error?) -> Void)
请求必须使用复用 API 令牌(在 CloudKit 仪表板中创建)和 Web 令牌。请使用以下方法创建 Web 令牌:
restrictTokens(forContainersWithAPITokens containerTokens: [CKContainer: String]) -> [CKContainer:String]
作者
Simen Gangstad, [邮箱地址隐藏]
许可协议
SwiftyCloudKit遵循MIT许可证。有关更多信息,请参阅LICENSE文件。