¿Se está registrando para notificaciones Push en Xcode 8 / Swift 3.0?

Intento que mi aplicación funcione en Xcode 8.0 y me encuentro con un error. Sé que este código funcionó bien en versiones anteriores de swift, pero asumo que el código para esto se cambia en la nueva versión. Aquí está el código que bash ejecutar:

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

El error que obtengo es “Etiquetas de argumento ‘(paraTipos :, categorías :)’ no coinciden con ninguna sobrecarga disponible”

¿Hay algún otro comando que pueda intentar que esto funcione?

    Importe el marco UserNotifications y agregue UNUserNotificationCenterDelegate en AppDelegate.swift

    Solicitar permiso de usuario

     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 } 

    Obteniendo token de dispositivo

     func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { let deviceTokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)}) print(deviceTokenString) } 

    En caso de error

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

    En caso de que necesite saber los permisos otorgados

     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") } } 
     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 } 

    Tuve problemas con las respuestas aquí al convertir el objeto DeviceToken Data a una cadena para enviar a mi servidor con la versión beta actual de Xcode 8. Especialmente la que estaba usando deviceToken.description como en 8.0b6 que devolvería “32 Bytes”, que no es muy útil 🙂

    Esto es lo que funcionó para mí …

    Cree una extensión en Data para implementar un método “hexString”:

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

    Y luego use eso cuando reciba la callback desde el registro para notificaciones remotas:

     func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { let deviceTokenString = deviceToken.hexString() // Send to your server here... } 

    En iOS10 en lugar de su código, debe solicitar una autorización de notificación con lo siguiente: (No olvide agregar el Marco de UserNotifications )

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

    Además, el código correcto para usted es (use en el else de la condición anterior, por ejemplo):

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

    Finalmente, asegúrese de que la Push Notification esté activada en el target -> Capabilities -> Push notification . (activarlo)

     import UserNotifications 

    A continuación, vaya al editor del proyecto para su objective, y en la pestaña General, busque la sección de Frameworks vinculados y bibliotecas.

    Haga clic en + y seleccione 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]) } 

    Utilice los métodos de delegado de notificación

     // 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)") } 

    Para recibir notificaciones push

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

    La configuración de notificaciones push está habilitando la función dentro de Xcode 8 para su aplicación. Simplemente vaya al editor del proyecto para su objective y luego haga clic en la pestaña Capacidades . Busque notificaciones automáticas y active su valor.

    Verifique el enlace a continuación para obtener más métodos de delegado de notificación

    Manejo de notificaciones locales y remotas UIApplicationDelegateManejo de notificaciones locales y remotas

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

    Bueno, este trabajo para mí. Primero en AppDelegate

     import UserNotifications 

    Entonces:

      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() } } 

    Para obtener devicetoken:

      func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { let deviceTokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)}) } 

    Encabeza, deberías usar el hilo principal para esta acción.

     let center = UNUserNotificationCenter.current() center.requestAuthorization(options:[.badge, .alert, .sound]) { (granted, error) in if granted { DispatchQueue.main.async(execute: { UIApplication.shared.registerForRemoteNotifications() }) } } 

    Primero , escuche el estado de notificación del usuario, es decir, registerForRemoteNotifications() para obtener el token del dispositivo APN;
    Segundo , solicite autorización. Al ser autorizado por el usuario, deviceToken se enviará al oyente, AppDelegate ;
    Tercero , reporte el token del dispositivo a su servidor.

     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) { // } } 

    La respuesta de ast1 es muy simple y útil. Funciona para mí, muchas gracias. Solo quiero señalarlo aquí, para que las personas que necesitan esta respuesta puedan encontrarlo fácilmente. Por lo tanto, aquí está mi código de registro de notificaciones locales y remotas (push).

      //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's 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 } 

    Simplemente haga lo siguiente en didFinishWithLaunching: :

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

    Recuerde sobre el estado de importación:

     import UserNotifications 
     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 } 

    Eche un vistazo a este código comentado:

     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)") } } 

    ¡Avíseme si hay algún problema!