0

I created a simple empty iOS application with XCode 11.5. With my device iOS 13.5.1, I am tying to implement push notifications but I dont receive the device push token or any error.

What am I doing wrong? The method didRegisterForRemoteNotificationsWithDeviceToken is never called.

With following code:

import UIKit
import UserNotifications

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterDelegate {

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // Override point for customization after application launch.
    registerForRemoteNotification()

    return true
}

func registerForRemoteNotification() {
    if #available(iOS 10.0, *) {
        let center  = UNUserNotificationCenter.current()
        center.delegate = self
        center.requestAuthorization(options: [.sound, .alert, .badge]) { (granted, error) in
            print("Authorization executed")
        }
        UIApplication.shared.registerForRemoteNotifications()
    }
    else {
        UIApplication.shared.registerUserNotificationSettings(UIUserNotificationSettings(types: [.sound, .alert, .badge], categories: nil))
        UIApplication.shared.registerForRemoteNotifications()
    }
}

// MARK: UISceneSession Lifecycle

func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
    // Called when a new scene session is being created.
    // Use this method to select a configuration to create the new scene with.
    return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}

func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
    // Called when the user discards a scene session.
    // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
    // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}

func application(
  _ application: UIApplication,
  didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data
) {
  let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) }
  let token = tokenParts.joined()
  print("Device Token: \(token)")
}

func application(
  _ application: UIApplication,
  didFailToRegisterForRemoteNotificationsWithError error: Error) {
  print("Failed to register: \(error)")
}

}

I have following output in the console:

Requesting permission
2020-06-06 12:13:23 +0000
Authorization executed
Requesting permission
2020-06-06 12:13:24 +0000
...
...
...

Screenshot: Screenshot of capabilities

  • 1
    See [here](https://stackoverflow.com/questions/28128490/didregisterforremotenotificationswithdevicetoken-not-called-in-ios8-but-didregi/59156989#59156989) some users have reported a bug with **wifi** when testing. Try connecting the phone to **cellular data**. – mfaani Jun 08 '20 at 03:38
  • 1
    I do experience the same problem, i.e. `Xcode 11.5.0` and iPhone device with `iOS 13.5.1` and `application:didRegisterForRemoteNotificationsWithDeviceToken:` not being called. And I've also tried using *cellular* data :/ And just to make it clear, this happens to me on a project where everything was working fine. I'm re-downloading `Xcode 11.4.1` right now to see if it works there. – mathz Jun 08 '20 at 09:43
  • 1
    "Funnily" enough same result for me in `Xcode 11.4.1`. https://developer.apple.com/system-status/ says APNS sandbox is up and running, so I guess it's another mystery... Unfortunately I don't have another testing device at hand. Well... – mathz Jun 08 '20 at 11:03
  • Some colleagues of mine confirmed that it works for them for the same project, so I think the bad guy really is my device. @selcukbeyhan try with a different device if you have one. – mathz Jun 08 '20 at 14:43
  • Yes, I took an old device iPhone S with iOS 11.4.1, guess what... it works now. I had reported this case to Apple. The think it is bug as well. – selcukbeyhan Jun 09 '20 at 14:28
  • as @mfaani said, token generation was successful when connected with mobile data. Thankyou – Akash Neeli Feb 08 '22 at 13:19

3 Answers3

0

Before trying this, make sure you have added this Capabilities...

under 'Capabilities', (next to General), 
 - Push Notifications option is turned ON`
 - and under Background Modes, Remote Notifications is turned ON

Ashish Langhe
  • 421
  • 1
  • 5
  • 15
0

For me it took like 6 hours after I recived all tokens that I requested. It really can take a long time sometimes

0

Import the UserNotifications framework and add the UNUserNotificationCenterDelegate in AppDelegate.swift

Request user permission

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {


    let notificationCenter = UNUserNotificationCenter.current()
    notificationCenter.requestAuthorization(options:[.badge, .alert, .sound]) { (granted, error) in
        // Enable or disable features based on authorization.
    }
    notificationCenter.delegate = self
    application.registerForRemoteNotifications()
    return true
}

Getting device token

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)

 {

let deviceTokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})
print(deviceTokenString)
}

In case of error

func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
    print("i am not available in simulator \(error)")
}

In case if you need to know the permissions granted

UNUserNotificationCenter.current().getNotificationSettings(){ (settings) in
        switch settings.soundSetting{
        case .enabled:

            print("enabled sound setting")

        case .disabled:

            print("setting has been disabled")

        case .notSupported:
            print("something vital went wrong here")
        }
    }

On Receiving notification following delegate will call:

func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
println("Recived: \(userInfo)")


//Parsing userinfo:
   var temp : NSDictionary = userInfo
   if let info = userInfo["aps"] as? Dictionary<String, AnyObject> 
            {
                var alertMsg = info["alert"] as! String
                var alert: UIAlertView!
                alert = UIAlertView(title: "", message: alertMsg, delegate: nil, cancelButtonTitle: "OK")
                alert.show()
            }
}

In your case, I think you need to replace:-

let tokenParts = deviceToken.map { data in String(format: "%02.2hhx", data) }

with,

let deviceTokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})
Apps Maven
  • 1,314
  • 1
  • 4
  • 17