如何使用同一个 CloudKit 数据库构建两个不同的应用程序?

Posted

技术标签:

【中文标题】如何使用同一个 CloudKit 数据库构建两个不同的应用程序?【英文标题】:How can I build two different apps using the same CloudKit database? 【发布时间】:2017-05-05 17:50:38 【问题描述】:

我需要做的是在我的开发者帐户下构建两个不同的应用程序。给用户一个看数据库中的数据,留一个方便我更改这个数据库。我正在使用 CloudKit、默认容器和公共数据库。

所以我现在尝试的是我有一个应用程序供用户使用,假设应用程序名称是“showdata”。在该应用程序中,我使用默认容器和公共数据库,如下所示:

let publicDatabase = CKContainer.default().publicCloudDatabase

然后我用它来执行查询:

query = CKQuery(recordType: "updateAndHold", predicate: NSPredicate(format: "TRUEPREDICATE"))
publicDatabase.perform(query!, inZoneWith: nil)  (records, error) in

在第二个应用程序中,我们将其命名为“updatedata”。 我应该怎么做才能使用相同的数据库和容器来更新数据。我试过这段代码:

let container = CKContainer.init(identifier: "iCloud.com.WMWios.showdata").publicCloudDatabase

但是当我获取任何记录时,它会给我一个错误,即没有使用该名称的权利:

query = CKQuery(recordType: "updateAndHold", predicate: NSPredicate(format: "TRUEPREDICATE"))
container.perform(query!, inZoneWith: nil)  (records, error) in

当我print(publicDatabase)print(container) 时,它的 ID 不同但标识符相同。

我需要有关该问题的帮助。如果您需要更多信息,请告诉我。

【问题讨论】:

【参考方案1】:

此代码使用命名的 icloud 数据库检查授权,并包括广泛的错误检查。

func isAuthorized4Cloud() 
    appDelegate = UIApplication.shared.delegate as! AppDelegate
    container = CKContainer(identifier: "iCloud.blah.com")
    publicDB = container.publicCloudDatabase
    privateDB = container.privateCloudDatabase
    var userID: CKRecordID!
    container.fetchUserRecordID( completionHandler:  recordID, error in
        guard error == nil else 
            if let ckerror = error as? CKError 
                if ckerror.code == CKError.requestRateLimited 
                    let retryInterval = ckerror.userInfo[CKErrorRetryAfterKey] as? TimeInterval
                    DispatchQueue.main.async 
                        Timer.scheduledTimer(timeInterval: retryInterval!, target: self, selector: #selector(self.files_searchSet), userInfo: nil, repeats: false)
                    
                 else if ckerror.code == CKError.zoneBusy 
                    let retryInterval = ckerror.userInfo[CKErrorRetryAfterKey] as? TimeInterval
                    DispatchQueue.main.async 
                        Timer.scheduledTimer(timeInterval: retryInterval!, target: self, selector: #selector(self.files_searchSet), userInfo: nil, repeats: false)
                    
                 else if ckerror.code == CKError.limitExceeded 
                    let retryInterval = ckerror.userInfo[CKErrorRetryAfterKey] as? TimeInterval
                    DispatchQueue.main.async 
                        Timer.scheduledTimer(timeInterval: retryInterval!, target: self, selector: #selector(self.files_searchSet), userInfo: nil, repeats: false)
                    
                 else if ckerror.code == CKError.notAuthenticated 
                    NotificationCenter.default.post(name: Notification.Name("noCloud"), object: nil, userInfo: nil)
                 else if ckerror.code == CKError.networkFailure 
                    NotificationCenter.default.post(name: Notification.Name("networkFailure"), object: nil, userInfo: nil)
                 else if ckerror.code == CKError.networkUnavailable 
                    NotificationCenter.default.post(name: Notification.Name("noWiFi"), object: nil, userInfo: nil)
                 else if ckerror.code == CKError.quotaExceeded 
                    NotificationCenter.default.post(name: Notification.Name("quotaExceeded"), object: nil, userInfo: nil)
                 else if ckerror.code == CKError.partialFailure 
                    NotificationCenter.default.post(name: Notification.Name("partialFailure"), object: nil, userInfo: nil)
                 else if (ckerror.code == CKError.internalError || ckerror.code == CKError.serviceUnavailable) 
                    NotificationCenter.default.post(name: Notification.Name("serviceUnavailable"), object: nil, userInfo: nil)
                
             // end of guard statement
            return
        

        if error == nil 
            userID = recordID
            NotificationCenter.default.post(name: Notification.Name("cloudConnected"), object: nil, userInfo: nil)
        
    )

您可能还想在 cloudkit 仪表板中查看数据库本身的权限,该仪表板将控制应用是否可以写入给定数据库。

【讨论】:

以上是关于如何使用同一个 CloudKit 数据库构建两个不同的应用程序?的主要内容,如果未能解决你的问题,请参考以下文章

用于网站和 iOS 的 CloudKit

是否可以使用 CloudKit 从 iCloud 驱动器获取数据

如何解决设备之间的 CloudKit 功能不一致

如何使用 CloudKit 将条目从公共数据库保存到私有数据库

CloudKit 不发送更新通知

cloudKit:公共数据库中的 CKFetchRecordChangesOperation