Alisher Baigazin
Alisher Baigazin

Reputation: 693

How to detect push notification token change and update server only when changed

I'm working with iOS push notifications (APNs) and need to update my server with the device's push notification token whenever it's initially registered or changes.

Apple's documentation explicitly advises against caching the device token, stating it can change in various situations.

However, I want to avoid unnecessary updates to my server by sending the same token value repeatedly if it hasn't actually changed. I'm looking for a way to detect a change in the push notification token before sending it to my backend(without actually caching???)

Upvotes: 0

Views: 62

Answers (2)

Rob
Rob

Reputation: 438102

The documentation you reference says:

Important

Never cache device tokens in local storage. APNs issues a new token when the user restores a device from a backup, when the user installs your app on a new device, and when the user reinstalls the operating system. You get an up-to-date token each time you ask the system to provide the token.

While that note starts with a sweeping and categorical “never cache device tokens in local storage” statement, the real concern is that we should never provide our servers with old, cached push notification tokens, but rather always should use the most recent token that the OS supplied to our delegate method. As that documentation says, the concern is that “tokens can change periodically, so caching the value risks sending an invalid token to your server.”

But that does not mean that you cannot cache the token for other reasons. So, if you want to dedupe redundant “here is my token” requests to your server, go ahead and cache the previous token, and check to see if the new token is actually different before updating your server.

Upvotes: 1

THEJAS
THEJAS

Reputation: 109

You can make use of simple computed property without actually storing it. Make use of didSet property observer to get notified whenever the values changes.

var deviceToken: String? {
    didSet {
        if oldValue != deviceToken, let newToken = deviceToken {
            updateServer(with: newToken)
        }
    }
}

private func updateServer(with token: String) {
    print("Updating server with new token: \(token)")
    // Make API request to update token
}

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    let tokenString = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
    print("Device Token: \(tokenString)")
    deviceToken = tokenString
    // Set this token to deviceToken variable
    // It'll update server whenever it changes
}

willSet also works, but its best to update after completing changes.

Upvotes: 0

Related Questions