Search code examples
iosswiftcloudkit

How can I get missed CloudKit notification while app is in the background mode?


  1. CloudKit manages my notifications (not my dedicated server)
  2. My first device changes something in CloudKit Container and pushes notification.
  3. ... but on my second device my app is currently running in background mode. So, the notification arrives to device with Alert, but the app itself doesn't know about it.

What is the elegant and effective way to catch this one missed notification (or even more) when the app goes back to the foreground mode?

Suppose the change is related to my top visible controller, and I would like to apply that change without fetching anything on viewDidAppear:.


Solution

  • Simply you can do the following, implemented inside UIApplicationDelegate method:

    func applicationWillEnterForeground(application: UIApplication) {
    
        var queryNotifications = [CKQueryNotification]()
        let operation = CKFetchNotificationChangesOperation(previousServerChangeToken: nil)
    
        operation.notificationChangedBlock = { notification in
    
            if let queryNotification = notification as? CKQueryNotification {
                queryNotifications.append(queryNotification)
            }
        }
    
        operation.fetchNotificationChangesCompletionBlock = { token, error in
    
            var notificationIdentifiers = [CKNotificationID]()
            for queryNotification in queryNotifications {
    
                let recordID = queryNotification.recordID!
    
                //here you can do enything you need with your recordID
                container.publicCloudDatabase.fetchRecordWithID(recordID, completionHandler: { object, error in
    
                    notificationIdentifiers.append(queryNotification.notificationID!)
    
                    if queryNotifications.count == notificationIdentifiers.count {
    
                        let operationQueue = NSOperationQueue()
                        operationQueue.addOperation(CKMarkNotificationsReadOperation(notificationIDsToMarkRead: notificationIdentifiers))
                    }
                })
            }
        }
    
        let operationQueue = NSOperationQueue()
        operationQueue.addOperation(operation)
    }