如何接收有关与我共享的记录所做更改的cloudkit通知?

时间:2017-10-17 06:46:50

标签: ios swift push-notification cloudkit

我在两个不同的设备上有两个icloud帐户( A B )。从其中一个( A )我分享ckrecord到另一个( B ),如下所示:

let controller = UICloudSharingController { controller, preparationCompletionHandler in

    let share = CKShare(rootRecord: record)
    share[CKShareTitleKey] = "title" as CKRecordValue

    share[CKShareTypeKey] = "pl.blueworld.fieldservice" as CKRecordValue
    share.publicPermission = .readWrite

    let modifyOperation = CKModifyRecordsOperation(recordsToSave: [record, share], recordIDsToDelete: nil)
    modifyOperation.savePolicy = .ifServerRecordUnchanged
    modifyOperation.perRecordCompletionBlock = { record, error in
        print(error?.localizedDescription ?? "")
    }

    modifyOperation.modifyRecordsCompletionBlock = { records, recordIds, error in

        print(share.url)
        preparationCompletionHandler(share, CloudAssistant.shared.container, error)
    }

    CloudAssistant.shared.container.privateCloudDatabase.add(modifyOperation)
}

controller.delegate = self

UIViewController.top()?.present(controller, animated: true)

当第二台设备( B )接受cloudkit共享时,我会获取记录并订阅更改:

func application(_ application: UIApplication, userDidAcceptCloudKitShareWith cloudKitShareMetadata: CKShareMetadata) {

    let acceptSharesOperation = CKAcceptSharesOperation(shareMetadatas: [cloudKitShareMetadata])
    acceptSharesOperation.perShareCompletionBlock = { metadata, share, error in

        if let error = error {
            UIAlertController.show(withMessage: error.localizedDescription)
        } else {

            let operation = CKFetchRecordsOperation(recordIDs: [cloudKitShareMetadata.rootRecordID])
            operation.perRecordCompletionBlock = { record, _, error in

                if let error = error {
                    UIAlertController.show(withMessage: error.localizedDescription)
                } else if let record = record {
                    CloudAssistant.shared.save(records: [record], recordIDsToDelete: [])

                    let options: CKQuerySubscriptionOptions = [.firesOnRecordCreation, .firesOnRecordUpdate, .firesOnRecordDeletion]
                    let territorySubscription = CKQuerySubscription(recordType: "Territory", predicate: NSPredicate(value: true), options: options)

                    let notificationInfo = CKNotificationInfo()
                    notificationInfo.shouldBadge = false
                    notificationInfo.shouldSendContentAvailable = true

                    territorySubscription.notificationInfo = notificationInfo

                    CloudAssistant.shared.sharedDatabase?.save(territorySubscription) { _, _ in }
                }
            }

            CloudAssistant.shared.container.sharedCloudDatabase.add(operation)
        }
    }
    acceptSharesOperation.qualityOfService = .userInteractive
    CKContainer(identifier: cloudKitShareMetadata.containerIdentifier).add(acceptSharesOperation)
}

现在来自设备 A 成功(我确信,更改会保存在iCloud中)对与他人共享的记录执行更新。但设备 B 并不知道,除非我再次手动获取记录。

但从另一方面来看,它运作良好。

如果我在与我共享的记录上成功执行更新(在设备 B 上),则设备 A 会获得有关更改的通知,一切正常。有什么区别?

如何订阅与我共享的记录的更改?

P.S当我能够参与时,我将为那些能帮助我的人开始200或更多的金额。

iOS 11,Swift 4,Xcode 9

1 个答案:

答案 0 :(得分:1)

这是我的调试订阅通知清单没有按预期显示。听起来你可能已经排除了其中一些。

  1. 确保该应用已注册通知
  2. 确保在此应用的设备上启用了通知
  3. 确保所有设备都使用相同的容器
  4. 在下一个应用启动时,使用fetchAllSubscriptionsWithCompletionHandler和NSLog读取所有订阅的每个子的详细信息(尤其是:subscriptionID,触发器选项,记录类型和谓词)。验证预期的子存在。验证每个子谓词是否符合预期(在这种情况下,比较您在两个设备上找到的谓词)。
  5. 我浪费了大量时间调试"缺少"通知时间:

    1. 我的本地构建版本使用TEST环境,TestFlight用户正在访问PROD环境。调试步骤2发现了这一点。
    2. 当无意中重新使用订阅ID时,每个新子包覆写前一个。调试步骤4最终揭示了问题
    3. 到目前为止,这四个调试步骤帮助我了解了我所有的"缺失的通知"问题。一旦我明白为什么通知没有出现,就缩小了哪个代码块负责。