4

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
Renee Olson
  • 267
  • 1
  • 15
  • I think CloudKit doesn't work with compound predicates. I think I read about it somewhere but can't find a precise link. But I found a rdar about the issue: http://www.openradar.me/18807663 – Dima Deplov Jun 06 '16 at 11:52
  • Thank you @flinth. I've not revisited this in a while to confirm, but that's disappointing. – Renee Olson Jun 09 '16 at 22:55

2 Answers2

5

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.

Imperious
  • 53
  • 1
  • 8
  • Sorry for delayed response. Thanks for the info. I've actually moved away from Cloudkit for a while and have been using Firebase lately. But if I ever need to go back to Cloudkit this is good to know. Thanks! – Renee Olson May 06 '17 at 01:00
  • @ReneeOlson Not a problem, and you're welcome - it's definitely not very intuitive, so hopefully this saves others from having to deal with this issue. – Imperious May 06 '17 at 19:19
  • @Imperious Do you have a link to where it discusses this on Apple's website? I still can't get it to work. – Clifton Labrum Jul 29 '18 at 05:37
  • @CliftonLabrum I looked briefly but I can't seem to find it, perhaps they've updated their documentation. I transitioned to Firebase so I haven't been using CloudKit for the past year, but I'll take a deeper look at their documentation tomorrow and if I don't find anything then maybe I can find my code to show an example. Sorry about that! – Imperious Jul 31 '18 at 04:34
  • I was finally able to get it to work. Using the `CKRecord` as you described is correct. I wasn’t pointing my record to the correct zone. Once I did, the notifications started working. Thanks! – Clifton Labrum Jul 31 '18 at 07:33
1

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.

Ian
  • 19
  • 1
  • 3
  • Thanks @ mustache. I tried your predicate and unfortunately the push notification never comes. Perhaps I'm testing it wrong, but I thought apple said to test if the notification comes via the dashboard. So I start the app with a different iCloud account and put it into the background. Then I add the new record in the dashboard. Is this right? The subscription in the dashboard using your predicate looks identical to what it was before - Notifications.read (equals string) Notifications.user (equals reference). – Renee Olson May 14 '15 at 06:16
  • Also since latest Xcode version, it acts odd - I had to get rid of the subscriptionID & use the convenience init because even though I deleted the subscription in the dashboard, the first time I subscribe it now gives error - "invalid attempt to update record from type '_sub_trigger_sub_2ded4b5120b4a2aae398d61a681d5599' to '_sub_trigger_sub_f678ae78884bd7ce081d07cb60385af1'"; uuid = ....; container ID = ....” However, the subscription is in the dashboard. Before, the first time it let me subscribe with same subscriptionID after I deleted it & 2nd attempt gave me error saying it was duplicate. – Renee Olson May 14 '15 at 06:41
  • How weird...now that error behavior stopped suddenly and works as expected. It gave the error like 3 times before. I'm starting to wonder if there's an issue with my computer and my install of Xcode. Have you ever gotten a similar error after deleting a subscription and then re-subscribing using the same subscriptionID? – Renee Olson May 14 '15 at 06:41
  • So, the predicates (mine & yours) appear to work, and the subscription is in the dashboard, but the push notification never comes for the user. And it's not an issue with my push notification code/setup, as I can get a simple "True" predicate to work for a query subscription. If you or anyone can replicate my issue, and you agree I'm testing the push notification correctly (first comment), then this may be a cloudkit bug. Problem is I can't find another example of subscriptions and references used together to verify if I'm doing anything wrong. – Renee Olson May 14 '15 at 07:10
  • Since CloudKit is mostly a black box, it is really hard to tell what is going on behind the scenes. Have you tried resetting the development environment before experimenting with new approaches? – Ian May 14 '15 at 07:11
  • No. Do you think that will help? I've avoided doing that because there are some record types I want to keep as I develop and I'm not using the "just-in-time schema" to populate these record types. I really want to know if what I'm trying to do is even supported by subscriptions and there's very limited info out there and none of my books, site, etc are using it the way I'm trying to. – Renee Olson May 14 '15 at 19:30
  • You should at least try a reset. If you are certain about your schema, you can deploy it to production and when you reset the development environment the schema will be created for you. But be warned that in production you can only add new fields or types but not update or delete. – Ian May 14 '15 at 20:45
  • I've not nailed down the schema yet. But I will likely try the reset as a last ditch effort. Thanks for your advice. – Renee Olson May 14 '15 at 20:49
  • Renee, this was a long time ago. Did you ever find a resolution? I am running into a very similar issue with CloudKit. – user3069232 Feb 21 '16 at 08:00
  • @user3069232 ...sorry missed your comment. I've not revisited this in a long time, so I'm not sure if there's a resolution, but do see the comment above under my post. Have you had any luck? – Renee Olson Jun 09 '16 at 22:57