问题
I'm trying to setup a CKSubscription for records that contain a field with a CKReference to the user. But anytime a record is created, it ignores this part of the compoundPredicate and the notification never comes. Is there something different about using a CKReference in a predicate for a CKSubscription? I go into the dashboard to enter a new record under my own user recordID (while running another user in simulator) because I believe I read that if the record comes from the device, it won't receive the notification. Any insight is greatly appreciated, as I've been stuck on this for a week and cannot find anything online specific to this. I'm able to get true type predicate notifications, so I think my basic setup is ok.
In the dashboard I see one generic subscription for both test users, but not any specific recordID for either user (does this matter?):
Notifications.read (equals string)
Notifications.user (equals reference)
When I do the fetchAllSubscriptionsWithCompletionHandler method, it does show the current user's specific recordID for this device as the CKReference in the debugger. So I don't know why it won't work.
Here's my code where I create the CKReference first and then use it for my predicate:
var recordIDString = CKRecordID(recordName: "_a86dac8ee05f8c6ab35746bf9663d7b8")
// I normally store this string in the NSUserDefaults.
let userRef = CKReference(recordID: recordIDString, action: .DeleteSelf)
let predicate = NSPredicate(format: "user = %@", userRef)
let predicateTwo = NSPredicate(format: "read = %@", "")
// I want the read field to be empty, which tells me user has not read my internal app notif.
let compoundPred = NSCompoundPredicate(type: .AndPredicateType, subpredicates: [predicate, predicateTwo])
Now I set-up the subscription like this:
let subscription = CKSubscription(recordType: "Notifications",
predicate: compoundPred,
options: .FiresOnRecordCreation)
let notificationInfo = CKNotificationInfo()
notificationInfo.alertBody = "Someone replied to your post"
notificationInfo.shouldBadge = true
subscription.notificationInfo = notificationInfo
publicDB.saveSubscription(subscription,
completionHandler: ({subscription, error in.....etc})
// handling this part
回答1:
I had this same issue, and stumbled upon this piece of information on apples website:
When creating a subscription whose predicate contains a CKReference field, be sure to use a CKRecordID object as the value for the field when creating the predicate. Using a CKRecord object in this case doesn't currently work.
When I changed my predicate for my CKQuerySubscription to use a CKRecordID instead of a CKReference it worked as expected. I realize this is an old thread but I struggled to find an answer to this issue, since the predicate seems to behave differently betwixt CKQuery and CKQuerySubscription.
回答2:
Initialise your subscription with NSPredicate
instead of NSCompoundPredicate
:
let predicate = NSPredicate(format: "user = %@ AND read = %@",
argumentArray: [userRef, ""])
let subscription = CKSubscription(recordType: "Notifications",
predicate: predicate,
options: .FiresOnRecordCreation)
In my experience with CloudKit this should work.
来源:https://stackoverflow.com/questions/29786016/cloudkit-subscription-notification-for-ckreference-not-working-as-expected