【问题标题】:How to receive cloudkit notifications about changes made on record shared with me?如何接收关于与我共享的记录所做更改的 cloudkit 通知?
【发布时间】:2018-03-28 18:51:13
【问题描述】:

我在两个不同的设备上有两个 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

【问题讨论】:

  • 我的理解是-“当所有者修改共享记录时,其他设备没有收到有关通知的更新,但其他方式运行良好”?
  • 没错...现在就是这样
  • 您是否在其他设备上注册了推送通知?
  • 对于推送通知在两者上都注册了。一定是因为在两台设备上都编译了同一个应用程序......并且在一种情况下它可以工作

标签: ios swift push-notification cloudkit


【解决方案1】:

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

  1. 确保应用已注册通知
  2. 确保在设备上为此应用启用通知
  3. 确保所有设备都使用同一个容器
  4. 在下一次应用启动时,使用fetchAllSubscriptionsWithCompletionHandler 和NSLog 读取所有订阅的每个订阅的详细信息(特别是:订阅ID、触发器选项、记录类型和谓词)。验证预期的 subs 是否存在。验证每个子的谓词是否符合预期(在这种情况下,比较您在两台设备上找到的谓词)。

我在以下情况下浪费了大量时间调试“丢失”通知:

  1. 我本地构建的版本正在使用 TEST 环境,而 TestFlight 用户正在访问 PROD 环境。调试第 2 步发现了这一点。
  2. 当无意中重复使用订阅 ID 时,每个新的订阅 ID 都会覆盖之前的订阅 ID。调试第 4 步最终发现了问题

到目前为止,这四个调试步骤已经帮助我理解了我所有的“丢失通知”问题。一旦我理解了为什么没有出现通知,就会缩小哪个代码块负责。

【讨论】:

  • 要获取订阅,您需要先订阅更改...就是这种情况...它不起作用...我订阅了更改,但它仍然没有收到来自 OWNER 的通知记录(但所有者从其他用户那里得到通知)
  • 在用户机器上调用FetchAllSubscriptions时,找到了多少个sub?你预计有多少?
  • 获取所有订阅的原因是什么?它们可能会被提取用于数据库。而且我认为我需要它们来共享数据库,对吗?我会在一天之内检查它...
  • 第 4 步是验证 subs 是否在用户设备上正确创建。
  • 此代码不起作用。当我不是记录的所有者时,我实际上应该怎么做才能收到通知?
猜你喜欢
  • 2018-05-27
  • 1970-01-01
  • 2015-10-21
  • 1970-01-01
  • 1970-01-01
  • 2019-04-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多