Register for push notifications in Xcode 8 / Swift 3.0?

I am trying to get my application to work in Xcode 8.0 and I am confused about the error. I know that this code worked fine in previous versions of swift, but I assume that the code for this has been changed in the new version. Here is the code I'm trying to run:

let settings = UIUserNotificationSettings(forTypes: [.Sound, .Alert, .Badge], categories: nil) UIApplication.sharedApplication().registerUserNotificationSettings(settings) UIApplication.shared().registerForRemoteNotifications() 

The error I get is "Argument Labels" (forTypes :, categories :) "do not match any available overloads"

Is there any other team with which I could try to do this?

+104
ios ios10 swift3 push-notification unusernotificationcenter
Jun 22 '16 at 0:01
source share
14 answers

Import the UserNotifications structure and add UNUserNotificationCenterDelegate to AppDelegate.swift

Request user permission

 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { let center = UNUserNotificationCenter.current() center.requestAuthorization(options:[.badge, .alert, .sound]) { (granted, error) in // Enable or disable features based on authorization. } 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 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") } } 
+278
Jun 22 '16 at 11:41
source share

 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { if #available(iOS 10, *) { //Notifications get posted to the function (delegate): func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void)" UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in guard error == nil else { //Display Error.. Handle Error.. etc.. return } if granted { //Do stuff here.. //Register for RemoteNotifications. Your Remote Notifications can display alerts now :) DispatchQueue.main.async { application.registerForRemoteNotifications() } } else { //Handle user denying permissions.. } } //Register for remote notifications.. If permission above is NOT granted, all notifications are delivered silently to AppDelegate. application.registerForRemoteNotifications() } else { let settings = UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil) application.registerUserNotificationSettings(settings) application.registerForRemoteNotifications() } return true } 
+44
Jun 22 '16 at 0:40
source share

I am having problems with the answers here to convert the deviceToken Data object to a string to send to my server with the current beta version of Xcode 8. Especially the one that used deviceToken.description like in 8.0b6, which would return "32 Bytes" which is not very useful :)

This is what worked for me ...

Create an extension for Data to implement the hexString method:

 extension Data { func hexString() -> String { return self.reduce("") { string, byte in string + String(format: "%02X", byte) } } } 

And then use this when you receive a registration callback for remote notifications:

 func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { let deviceTokenString = deviceToken.hexString() // Send to your server here... } 
+19
Aug 27 '16 at 9:04 on
source share
 import UserNotifications 

Then go to the project editor for your purpose and on the General tab, find the Linked Frameworkworks and Libraries section.

Click + and select UserNotifications.framework:

 // iOS 12 support if #available(iOS 12, *) { UNUserNotificationCenter.current().requestAuthorization(options:[.badge, .alert, .sound, .provisional, .providesAppNotificationSettings, .criticalAlert]){ (granted, error) in } application.registerForRemoteNotifications() } // iOS 10 support if #available(iOS 10, *) { UNUserNotificationCenter.current().requestAuthorization(options:[.badge, .alert, .sound]){ (granted, error) in } application.registerForRemoteNotifications() } // iOS 9 support else if #available(iOS 9, *) { UIApplication.shared.registerUserNotificationSettings(UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil)) UIApplication.shared.registerForRemoteNotifications() } // iOS 8 support else if #available(iOS 8, *) { UIApplication.shared.registerUserNotificationSettings(UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil)) UIApplication.shared.registerForRemoteNotifications() } // iOS 7 support else { application.registerForRemoteNotifications(matching: [.badge, .sound, .alert]) } 

Use notification delegate methods

 // Called when APNs has assigned the device a unique token func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { // Convert token to string let deviceTokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)}) print("APNs device token: \(deviceTokenString)") } // Called when APNs failed to register the device for push notifications func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { // Print the error to console (you should alert the user that registration failed) print("APNs registration failed: \(error)") } 

To receive push notifications

 func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) { completionHandler(UIBackgroundFetchResult.noData) } 

Configuring push notifications includes a feature in Xcode 8 for your application. Just go to the project editor for your purpose and then click on the Features tab . Locate push notifications and set its value to ON .

Check out the link below for more notification delegate methods.

Handling Local and Remote Notifications UIApplicationDelegate - Handling Local and Remote Notifications

https://developer.apple.com/reference/uikit/uiapplicationdelegate

+18
Mar 09 '17 at 5:29 on
source share

In iOS10, instead of your code, you must request authorization for a notification with the following: (Remember to add the UserNotifications Framework)

 if #available(iOS 10.0, *) { UNUserNotificationCenter.current().requestAuthorization([.alert, .sound, .badge]) { (granted: Bool, error: NSError?) in // Do something here } } 

Also, the correct code is for you (use the else previous condition, for example):

 let setting = UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil) UIApplication.shared().registerUserNotificationSettings(setting) UIApplication.shared().registerForRemoteNotifications() 

Finally, make sure Push Notification activated in targetCapabilitiesPush Notification . (set it to On )

+17
Jun 22 '16 at 0:36
source share

Ok, this work is for me. First in AppDelegate

 import UserNotifications 

Then:

  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: 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 if error == nil{ UIApplication.shared.registerForRemoteNotifications() } } } else { UIApplication.shared.registerUserNotificationSettings(UIUserNotificationSettings(types: [.sound, .alert, .badge], categories: nil)) UIApplication.shared.registerForRemoteNotifications() } } 

Get devicetoken:

  func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { let deviceTokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)}) } 
+8
Oct 17 '16 at 13:28
source share

Head, you must use the main thread for this action.

 let center = UNUserNotificationCenter.current() center.requestAuthorization(options:[.badge, .alert, .sound]) { (granted, error) in if granted { DispatchQueue.main.async(execute: { UIApplication.shared.registerForRemoteNotifications() }) } } 
+4
Oct 17 '17 at 18:38 on
source share

First , listen to the notification status of the user, i.e. registerForRemoteNotifications() to get the device’s APNs token;
Secondly , request authorization. Upon user authorization, the AppDelegate device will be sent to the listener, AppDelegate ;
Thirdly , report the device token to your server.

 extension AppDelegate { /// 1. 监听 deviceToken UIApplication.shared.registerForRemoteNotifications() /// 2. 向操作系统索要推送权限(并获取推送 token) static func registerRemoteNotifications() { if #available(iOS 10, *) { let uc = UNUserNotificationCenter.current() uc.delegate = UIApplication.shared.delegate as? AppDelegate uc.requestAuthorization(options: [.alert, .badge, .sound]) { (granted, error) in if let error = error { // 无论是拒绝推送,还是不提供 aps-certificate,此 error 始终为 nil print("UNUserNotificationCenter 注册通知失败, \(error)") } DispatchQueue.main.async { onAuthorization(granted: granted) } } } else { let app = UIApplication.shared app.registerUserNotificationSettings(UIUserNotificationSettings(types: [.badge, .sound, .alert], categories: nil)) // 获取用户授权} } // 在 app.registerUserNotificationSettings() 之后收到用户接受或拒绝及默拒后,此委托方法被调用func application(_ app: UIApplication, didRegister notificationSettings: UIUserNotificationSettings) { // 已申请推送权限,所作的检测才有效// a 征询推送许可时,用户把app切到后台,就等价于默拒了推送// b 在系统设置里打开推送,但关掉所有形式的提醒,等价于拒绝推送,得不token,也收不推送// c 关掉badge, alert和sound 时,notificationSettings.types.rawValue 等于 0 和 app.isRegisteredForRemoteNotifications 成立,但能得到token,也能收到推送(锁屏和通知中心也能看到推送),这说明types涵盖并不全面// 对于模拟器来说,由于不能接收推送,所以 isRegisteredForRemoteNotifications 始终为 false onAuthorization(granted: app.isRegisteredForRemoteNotifications) } static func onAuthorization(granted: Bool) { guard granted else { return } // do something } } extension AppDelegate { func application(_ app: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { // } // 模拟器得不到 token,没配置 aps-certificate 的项目也得不到 token,网络原因也可能导致得不到 token func application(_ app: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { // } } 
+2
Nov 10 '17 at 14:12
source share

The answer from ast1 is very simple and useful. This works for me, thank you very much. I just want to understand this, so people who need this answer can easily find this. So, here is my code from registering local and remote (push) notifications.

  //1. In Appdelegate: didFinishLaunchingWithOptions add these line of codes let mynotif = UNUserNotificationCenter.current() mynotif.requestAuthorization(options: [.alert, .sound, .badge]) {(granted, error) in }//register and ask user permission for local notification //2. Add these functions at the bottom of your AppDelegate before the last "}" func application(_ application: UIApplication, didRegister notificationSettings: UNNotificationSettings) { application.registerForRemoteNotifications()//register for push notif after users granted their permission for showing notification } func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { let tokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)}) print("Device Token: \(tokenString)")//print device token in debugger console } func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { print("Failed to register: \(error)")//print error in debugger console } 
0
Sep 19 '16 at 8:19
source share

Just do the following in didFinishWithLaunching: ::

 if #available(iOS 10.0, *) { let center = UNUserNotificationCenter.current() center.delegate = self center.requestAuthorization(options: []) { _, _ in application.registerForRemoteNotifications() } } 

Remember the import statement:

 import UserNotifications 
0
May 10 '17 at 11:51
source share

@Team,

I created one example application that is used to request permission to notify a user. The repo also check that if the user is denied permission, it will display a warning as if we need your permission to notify .

NotificationPermission

Note. Right now, every time the application is used again, it asks "We need permission to notify", and if the user does not allow permission. You can change the frequency of the repeated permission request according to the requirements, such as whats application and other applications.

0
Jan 27 '19 at 14:26
source share
 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { let notificationCenter = UNUserNotificationCenter.current() notificationCenter.requestAuthorization([.alert , .sound]) { (finished, err) in if err == nil { application.registerForRemoteNotifications() } } return true } 
-one
Jun 22 '16 at 23:57
source share

Take a look at this comment:

 import Foundation import UserNotifications import ObjectMapper class AppDelegate{ let center = UNUserNotificationCenter.current() } extension AppDelegate { struct Keys { static let deviceToken = "deviceToken" } // MARK: - UIApplicationDelegate Methods func application(_: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { if let tokenData: String = String(data: deviceToken, encoding: String.Encoding.utf8) { debugPrint("Device Push Token \(tokenData)") } // Prepare the Device Token for Registration (remove spaces and < >) setDeviceToken(deviceToken) } func application(_: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { debugPrint(error.localizedDescription) } // MARK: - Private Methods /** Register remote notification to send notifications */ func registerRemoteNotification() { center.requestAuthorization(options: [.alert, .sound, .badge]) { (granted, error) in // Enable or disable features based on authorization. if granted == true { DispatchQueue.main.async { UIApplication.shared.registerForRemoteNotifications() } } else { debugPrint("User denied the permissions") } } } /** Deregister remote notification */ func deregisterRemoteNotification() { UIApplication.shared.unregisterForRemoteNotifications() } func setDeviceToken(_ token: Data) { let token = token.map { String(format: "%02.2hhx", arguments: [$0]) }.joined() UserDefaults.setObject(token as AnyObject?, forKey: "deviceToken") } class func deviceToken() -> String { let deviceToken: String? = UserDefaults.objectForKey("deviceToken") as? String if isObjectInitialized(deviceToken as AnyObject?) { return deviceToken! } return "123" } func isObjectInitialized(_ value: AnyObject?) -> Bool { guard let _ = value else { return false } return true } } extension AppDelegate: UNUserNotificationCenterDelegate { func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping(UNNotificationPresentationOptions) -> Swift.Void) { ("\(notification.request.content.userInfo) Identifier: \(notification.request.identifier)") completionHandler([.alert, .badge, .sound]) } func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping() -> Swift.Void) { debugPrint("\(response.notification.request.content.userInfo) Identifier: \(response.notification.request.identifier)") } } 

Let me know if there is any problem!

-one
May 14 '18 at 12:12
source share

Here is the code in Swift 4.1 and Xcode 9.3

  1. Enabling Push Notifications - Just go to the project editor for your purpose, and then click on the “Features” tab. Locate push notifications and set its value to ON.
  2. IOS 10 introduced a new structure called UserNotifications and must be imported to access the UNUserNotificationCenter class. Add the following import statement to the top of AppDelegate.swift

    import UserNotifications

Then go to the project editor for your purpose, and on the "General" tab, find the "Related Structures and Libraries" section.

Click + and select UserNotifications.framework

The user has completed the following APNS registration and processing methods

  //MARK: - Remote Notificaton extension AppDelegate: UNUserNotificationCenterDelegate { func registerForPushNotifications(application: UIApplication) { if #available(iOS 10.0, *) { UNUserNotificationCenter.current().requestAuthorization(options: [.badge, .sound, .alert], completionHandler: { (granted, _) in if granted { UIApplication.shared.registerForRemoteNotifications() } else { } }) } else { let notificationSettings = UIUserNotificationSettings( types: [.badge, .sound, .alert], categories: nil) UIApplication.shared.registerUserNotificationSettings(notificationSettings) } } func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { let deviceToken = deviceToken.hexString() Debug.Log(message: "Device Token - \(deviceToken.hexString())") } func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { Debug.Log(message: "Failed to register for RemoteNotifications") } @available(iOS 10.0, *) func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) { //Handle the notification if UIApplication.shared.applicationState == .inactive { let seconds = 1.0 let delay = seconds * Double(NSEC_PER_SEC) // nanoseconds per seconds let dispatchTime = DispatchTime.now() + Double(Int64(delay)) / Double(NSEC_PER_SEC) DispatchQueue.main.asyncAfter(deadline: dispatchTime, execute: { self.handlerRemoteNotification(response.notification.request.content.userInfo) }) } else { handlerRemoteNotification(response.notification.request.content.userInfo) } } func handlerRemoteNotification(_ userInfo: [AnyHashable: Any]) { if #available(iOS 10.0, *) { } else { if UIApplication.shared.applicationState != .active { return } } if let jsonString: String = userInfo["parameters"] as? String { let data = jsonString.data(using: String.Encoding.utf8, allowLossyConversion: false)! do { let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: AnyObject] if let json = json { // handle Json } } catch let error as NSError { Debug.Log(message: "Failed to load: \(error.localizedDescription)") } } } func application( _ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler handler: @escaping (UIBackgroundFetchResult) -> Void) { if UIApplication.shared.applicationState != .active { if let cId = userInfo["Number"] as? Int64 { // Push your ViewController } } else { } } } // Here extension for data extension Data { func hexString() -> String { return self.reduce("") { string, byte in string + String(format: "%02X", byte) } } } 
-one
May 14 '18 at 14:46
source share



All Articles