Xcode 9 (iOS 11) me muestra un error / advertencia al registrarme para la notificación Push (remota).
Aquí hay un mensaje de error
Y aquí está el código, lo intenté:
let center = UNUserNotificationCenter.current()
center.delegate = self
center.requestAuthorization(options: [.sound, .alert, .badge]) { (granted, error) in
if error == nil{
UIApplication.shared.registerForRemoteNotifications()
}
}
Línea de error / advertencia:
UIApplication.shared.registerForRemoteNotifications ()
¿Cómo resolver esto?
UIApplication.shared.registerForRemoteNotifications()
en el hilo principal. :) Vamos a google cómo llamarlo en el hilo principal ...UIApplication.shared.registerForRemoteNotifications()
no está relacionado con la interfaz de usuario (no avisa a los usuarios cuando obtiene el token para notificaciones silenciosas). Entonces, la línea que muestra el error es confusa. Sin embargo, registrarse para las insignias, alertas y sonidos está relacionado con la interfaz de usuario y es mucho mejor hacerlo desde el hilo principal ... así que, en general, todo el bloquecenter.requestAuthorization(options:...
debe hacerse desde el hilo principal ... tiene sentidoRespuestas:
En swift4
Puede resolver este problema con
DispatchQueue.main.async { UIApplication.shared.registerForRemoteNotifications() }
Espero que esto ayude ...
fuente
DispatchQueue.main.async(execute: UIApplication.shared.registerForRemoteNotifications())
Cannot invoke 'async' with an argument list of type '(execute: Void)'
error al usar tu ejemplo.DispatchQueue.main.async(execute: UIApplication.shared.registerForRemoteNotifications)
.execute
espera una función / cierre de tipo,() -> Void
así queregisterForRemoteNotifications
funcionadispatch_async(dispatch_get_main_queue(), ^{ //Do stuff });
Para Objective C, el siguiente código funciona
dispatch_async(dispatch_get_main_queue(), ^{ [[UIApplication sharedApplication] registerForRemoteNotifications]; });
fuente
TL; DR:
Todas las manipulaciones de la interfaz de usuario deben realizarse en el hilo principal para evitar problemas. Si no lo hizo, Main Thread Checker (función de depuración recién introducida en XCode 9) producirá problemas en tiempo de ejecución. Así que envuelva su código en el bloque Main Thread como se muestra a continuación para evitar fallas y advertencias de tiempo de ejecución.
DispatchQueue.main.async { UIApplication.shared.registerForRemoteNotifications() }
En versiones de Xcode anteriores a la ver. 9, las advertencias relacionadas con el hilo principal se imprimirían textualmente en el área de la consola. De todos modos, puede deshabilitar opcionalmente ( no es un enfoque recomendado ) el Comprobador de subprocesos principal en la configuración de diagnóstico en Editar esquema .
Explicación:
Apple introdujo una nueva opción de depuración en XCode 9 para verificar problemas en Runtime para UIKit y otras API que manipulan elementos de UI. Si hay algún cambio en los elementos de la interfaz de usuario de la API de UIKit en tiempo de ejecución, sin un bloque de hilo principal, es muy probable que cause fallas y fallas en la interfaz de usuario. El Comprobador de subprocesos principal está habilitado de forma predeterminada para detectar esos problemas en tiempo de ejecución. Puede deshabilitar el Comprobador de subprocesos principal en la ventana Editar esquema como se muestra a continuación, aunque realmente no se recomienda hacerlo:
Si tiene algún SDK o Frameworks más antiguo, al actualizar a Xcode 9, puede enfrentar esta advertencia ya que algunas de las llamadas al método UIKit no se habrían envuelto en Main Thread. Actualizarlos a la última versión solucionaría el problema (si el desarrollador lo sabe y lo soluciona).
Cita de las notas de la versión beta de XCode 9:
fuente
El mensaje de error es bastante claro: despacho
registerForRemoteNotifications
al hilo principal.Usaría el
granted
parámetro y manejaría el enerror
consecuenciacenter.requestAuthorization(options: [.sound, .alert, .badge]) { (granted, error) in if granted { DispatchQueue.main.async { UIApplication.shared.registerForRemoteNotifications() } } else { print(error!) // handle the error } }
fuente
Esta también es la forma correcta de hacerlo en Swift 4.0
UNUserNotificationCenter.current().delegate = self UNUserNotificationCenter.current().requestAuthorization(options: [.alert,.sound,.badge], completionHandler: {(granted,error) in if granted{ DispatchQueue.main.async { application.registerForRemoteNotifications() } } })
fuente
Espero que esto ayude
DispatchQueue.main.async(execute: { UIApplication.shared.registerForRemoteNotifications() })
fuente
Esto es lo que funcionó para mí. Cortesía de @ Mason11987 en el comentario aceptado arriba.
DispatchQueue.main.async() { code }
fuente