仅为更新而创建记录的CloudKit订阅不会触发

时间:2017-03-29 03:03:21

标签: ios push-notification swift3 cloudkit subscriptions

我正在尝试使用CloudKit保持多个设备同步。具体来说,我试图根据iCloud / CloudKit中存储的内容保持动作数据(动作人物细节)的属性一致。我正在使用订阅来在记录发生变化时通知。更新记录触发并收到很好。如果我将订阅分成两个单独的订阅 - 1个用于创建,1个用于更新,则不会触发。

let actionFigureRefernece = CKReference(recordID: actionFigureRecordId, action: .deleteSelf)
let predicate = NSPredicate(format:"actionFigureReference == %@", actionFigureRefernece)

图引用和细节属性的表布局:

 actionFigureReference Reference
 haveFigureCount Int(64)
 haveTheFigure Int(64)

这是代码。

func saveActionFigureSpecifics() {

    // set and save core data
    actionFigureSpecificsCoreData!.updateDate = NSDate()
    SharedData.sharedInstance.appDelegate.saveContext()

    // save to iCloud based on user preference
    if SharedData.sharedInstance.isUserPreferenceToUseICloud == true {
        // Private Database
        let privateDatabase = SharedData.sharedInstance.privateDatabase

        // record IDs
        let actionFigureRecordId = CKRecordID(recordName: actionFigureGlobalUniqueId)
        let actionFigureSpecificRecordId = CKRecordID(recordName: actionFigureSpecificsGlobalUniqueId)

        // Initialize Reference
        if actionFigureSpecificsRecord == nil {
            // set the record type
            actionFigureSpecificsRecord = CKRecord(recordType: kActionFigureSpecificsRecord, recordID: actionFigureSpecificRecordId)

            // set the record details
            let actionFigureReference = CKReference(recordID: actionFigureRecordId, action: .deleteSelf)
            actionFigureSpecificsRecord!.setObject(actionFigureReference, forKey: kActionFigureReference)
        }

        // iCloud attributes
        actionFigureSpecificsRecord!.setObject(actionFigureSpecificsCoreData!.haveTheFigure as CKRecordValue?, forKey: kHaveTheFigure)
        actionFigureSpecificsRecord!.setObject(actionFigureSpecificsCoreData!.haveFigureCount as CKRecordValue?, forKey: kHaveFigureCount)
        actionFigureSpecificsRecord!.setObject(actionFigureSpecificsCoreData!.wantTheFigure as CKRecordValue?, forKey: kWantTheFigure)
        actionFigureSpecificsRecord!.setObject(actionFigureSpecificsCoreData!.updateDate as CKRecordValue?, forKey: kUpdateDate)

        // Create subscription
        // push notification
        self.saveActionFigureSpecificsICloudSubscriptions(withReference: actionFigureRecordId) {
            results, error in

            if let error = error {
                print("Error saving subscription: \(error.localizedDescription)")
            }

            // Save Record
            privateDatabase!.save(self.actionFigureSpecificsRecord!) { (actionFigureRecord, error) -> Void in
                if (error != nil) {
                    DispatchQueue.main.async {
                        #if DEBUG
                            print("WARNING: Error saving specifics of \(actionFigureRecordId.recordName) \(error!)")
                        #endif

                        self.isActionFigureSpecificSetFromICloud = false
                    }
                } else {
                    DispatchQueue.main.async {
                        // set the record to the saved record.
                        self.actionFigureSpecificsRecord = actionFigureRecord!

                        let actionFigureReference = actionFigureRecord!.object(forKey: kActionFigureReference) as! CKReference
                        let actionFigureRecoreId = actionFigureReference.recordID
                        #if DEBUG
                            print("Save executed and successful on \(kActionFigureSpecificsRecord) for \(actionFigureRecoreId.recordName)")
                        #endif
                    }
                }
            }
        }
    }
}

订阅增加

func saveActionFigureSpecificsICloudSubscriptions(withReference actionFigureRecordId: CKRecordID, completion : @escaping (_ results: CKSubscription?, _ error : Error?) -> Void) {
    let privateDatabase = SharedData.sharedInstance.privateDatabase

    let subscriptionId = "\(actionFigureRecordId.recordName)_\(kActionFigureSpecificsRecord)_Subscription"

    // get subscriptions
    privateDatabase?.fetchAllSubscriptions(completionHandler: { (subscriptions, error) in

        if let err = error {
            #if DEBUG
                print("Fetch subscription failed \(err.localizedDescription)")
            #endif

            completion(nil, err)

            return

        } else {
            var isSubscriptionCreated: Bool = false

            for subscription in subscriptions! {
                //if subscriptionId == subscription.subscriptionID {
                if subscription.subscriptionID.contains(subscriptionId) {
                    #if DEBUG
                        print("subscription detail exists for \(subscription.subscriptionID)")
                    #endif

                    isSubscriptionCreated = true
                }

            }

            // if the subscription doesn't exist, create the subscription
            if isSubscriptionCreated == false {
                let actionFigureRefernece = CKReference(recordID: actionFigureRecordId, action: .deleteSelf)
                let predicate = NSPredicate(format:"actionFigureReference = %@", actionFigureRefernece)
                //let predicate = NSPredicate(value: true)

                let subscriptionIdInsert = "\(subscriptionId)"
                let subscription = CKQuerySubscription(recordType: kActionFigureSpecificsRecord, predicate: predicate, subscriptionID: subscriptionIdInsert, options: [.firesOnRecordCreation, .firesOnRecordUpdate])

                let notification = CKNotificationInfo()

                var actionFigure: ActionFigure?

                if let specificsDelegate = self.delegate as? ActionFigure {
                    actionFigure = specificsDelegate
                    notification.alertBody = "Action figure specifics \(actionFigure!.series) \(actionFigure!.actionFigureName) updated"
                }
                else {
                    notification.alertBody = "Action figure specifics updated"
                }

                notification.shouldBadge = true
                notification.soundName = "default"

                subscription.notificationInfo = notification

                privateDatabase?.save(subscription, completionHandler: ({returnRecord, error in
                    if let err = error {
                        #if DEBUG
                            print("subscription creation failed \(err.localizedDescription)")
                        #endif

                        completion(nil, err)

                        return

                    } else {
                        DispatchQueue.main.async() {
                            #if DEBUG
                                print("Success:  Subscription set up successfully for specifics on \(subscriptionId)")
                            #endif

                            completion(returnRecord, nil)

                            return
                        }
                    }
                }))
            }
            else {  // subscription exists
                completion(nil, nil)
                return
            }
        }
    })
}

AppDelegate功能

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

    SharedDataToyLine.sharedInstance.setToyLines()


    // Register to receive notification
    //create the notificationCenter
    let center  = UNUserNotificationCenter.current()
    center.delegate = self
    center.requestAuthorization(options: [.alert]) { (granted, error) in
        // nothing to do yet
    }

    application.registerForRemoteNotifications()

    // Google adds
    FIRApp.configure()
    GADMobileAds.configure(withApplicationID: kGADMobileAdsMobileAppId)

    // Amazon adds
    AmazonAdRegistration.shared().setAppKey(kAmazonMyToyChestAPIKey)

    return true
}

func userNotificationCenter(_ center: UNUserNotificationCenter,  willPresent notification: UNNotification, withCompletionHandler   completionHandler: @escaping (_ options:   UNNotificationPresentationOptions) -> Void) {

    completionHandler([.alert, .badge, .sound])

    let notification: CKNotification = CKNotification(fromRemoteNotificationDictionary: notification.request.content.userInfo as! [String : NSObject])

    if (notification.notificationType == CKNotificationType.query) {
        let queryNotification = notification as! CKQueryNotification
        let recordId: CKRecordID = queryNotification.recordID!
        #if DEBUG
            print("Foreground push for record name returned from push \(recordId.recordName)")
        #endif

        if let shareDataActionFigureArrayIndex = SharedDataActionFigure.sharedInstance.getIndexForActionFigure(byActionFigureSpecificsRecordId: recordId) {
            #if DEBUG
                print("Record index for push \(recordId.recordName) is \(shareDataActionFigureArrayIndex)")
            #endif

            SharedDataActionFigure.sharedInstance.actionFigureArray[shareDataActionFigureArrayIndex].actionFigureSpecifics.setActionFigureSpecificsFromPushNotification()
        }
    }
}

订阅

RecordType
    ActionFigureSpecifics
Trigger
    UPDATE<br>INSERT
Criteria
    ActionFigureSpecifics.actionFigureReference (equals reference)

0 个答案:

没有答案