I am struggling with the following subscription:
let predicate = NSPredicate(format: "gc_alias != %@ AND distanceToLocation:fromLocation:(%K,%@) < %f",
self.localPlayer!.alias!,
"location",
self.currentLocation!,
10)
let subscription = CKSubscription(recordType: "Player", predicate: predicate, options: .FiresOnRecordCreation)
subscription.zoneID = nil
let notification = CKNotificationInfo()
notification.alertBody = "Nearby Player within Range!"
notification.soundName = UILocalNotificationDefaultSoundName
subscription.notificationInfo = notification
let container = CKContainer.defaultContainer()
let publicDb = container.publicCloudDatabase
publicDb.saveSubscription(subscription) { (result, error) -> Void in
if error != nil {
print(error!.localizedDescription)
} else {
print("SUBSCRIBED SUCCESS")
print(result)
NSUserDefaults.standardUserDefaults().setBool(true, forKey: "subscribed")
}
}
Basically, when a new Player record is created or updated I log the user's location.
I want user A to be notified via Push when user B creates or updates their Player record and is within 10KM.
I believe I have the push permissions setup correctly in my app (user is prompted to confirm this before their sub is created, for example).
No pushes arriveth. Any ideas? Am I suffering from some fundamental CK misconception?
You don't seem to be registering for push notifications:
iOS Developer Library: Subscribing to Record Changes
Saving subscriptions to the database doesn’t automatically configure your app to receive notifications when a subscription fires. CloudKit uses the Apple Push Notification service (APNs) to send subscription notifications to your app, so your app needs to register for push notifications to receive them.
According to Hacking with Swift: Delivering notifications with CloudKit push messages: CKSubscription and saveSubscription you should:
Go to AppDelegate.swift and put this code into the didFinishLaunchingWithOptions method:
let notificationSettings = UIUserNotificationSettings(forTypes: [.Alert, .Sound], categories: nil)
UIApplication.sharedApplication().registerUserNotificationSettings(notificationSettings)
UIApplication.sharedApplication().registerForRemoteNotifications()
And
For the sake of completion, you could optionally also catch the didReceiveRemoteNotification message sent to your app delegate, which is called if a push message arrives while the app is running. Something like this ought to do the trick:
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
if let pushInfo = userInfo as? [String: NSObject] {
let notification = CKNotification(fromRemoteNotificationDictionary: pushInfo)
let ac = UIAlertController(title: "What's that Whistle?", message: notification.alertBody, preferredStyle: .Alert)
ac.addAction(UIAlertAction(title: "OK", style: .Default, handler: nil))
if let nc = window?.rootViewController as? UINavigationController {
if let vc = nc.visibleViewController {
vc.presentViewController(ac, animated: true, completion: nil)
}
}
}
}