Search code examples
iosxcodeswiftpush-notificationcloudkit

How to update CloudKit Subscriptions


I am trying to make a messaging app using iOS, Swift, and CloudKit. I have successfully made it and I have push notifications sent whenever somebody adds another message. However, I would like for the push notification's text to say what ever was on the message. Here is what I have tried:

Default code for sending notifications:

let subscription = CKSubscription(recordType: "Responses", predicate: NSPredicate(format: "TRUEPREDICATE", argumentArray: nil), options: .FiresOnRecordCreation)
let notification = CKNotificationInfo()
notification.alertBody = "New Message Sent"
notification.soundName = UILocalNotificationDefaultSoundName

subscription.notificationInfo = notification

CKContainer.defaultContainer().publicCloudDatabase.saveSubscription(subscription) { (result, error) -> Void in
    if error != nil {
        print(error!.localizedDescription)
    }
}

This allows me to send notifications for each message that says "New Message Sent". This is what I have tried for specified notifications:

//publicDB is the CKContainer.defaultContainer.publicDatabase
publicDB.fetchAllSubscriptionsWithCompletionHandler({ (subscriptions, error) in

    if error != nil {

        self.displayError(self.getStringFromError(error!))

    } else {

        for subscription in subscriptions! {

            subscription.notificationInfo?.alertBody = self.responseTextField.text

        }

    }

})

let record = CKRecord(recordType: "Responses")
record.setObject(currentUsername, forKey: "respondedBy")
record.setObject(responseTextField.text, forKey: "response")
publicDB.saveRecord(record) { (record, error) in
    //code for updating tables, etc.
    //Notification on other device sent
}

Setting the alertBody of the subscription (what I tried to do above) does not work. Is there any other solution for updating the alertBody of a subscription? Thanks!


Solution

  • subscriptions can not be updated. You first have to delete it and then recreate it.

    but then, why change the alertBody? You could initially set it to display the response field of the record. For doing that you should use something like this:

    notificationInfo?.alertLocalizationKey = "Response: %1$@"
    notificationInfo?.alertLocalizationArgs = ["response"]
    

    Then you also need this in your Localization.Strings file.

    "Response: %1$@" = "Response: %1$@";
    

    In your case you want to change the subscription each time a new message is created. You are setting the notification message the same as one of the fields of the record. Instead you could let CloudKit automatically send that field. You only have to create the subscription once. In the 2 code lines above the

    alertLocalizationKey is the key that is looked up in the Localization.Strings file and the alertLocalizationArgs are the CloudKit fields that will be used to replace the parameters.

    For more information about localization see for instance http://nshipster.com/nslocalizedstring/