objective c - clave - por qué didRegisterForRemoteNotificationsWithDeviceToken no se llama
prefijo de id de la app (19)
Estoy haciendo una aplicación en la que deseo implementar el servicio de notificación push de Apple. Estoy siguiendo las instrucciones paso a paso dadas en este tutorial .
Pero aún así, los métodos no son llamados. No sé qué está causando el problema. ¿Alguien puede ayudarme?
- (void)application:(UIApplication *)appdidRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
//NSString * token = [[NSString alloc] initWithData:deviceTokenencoding:NSUTF8StringEncoding];
NSString *str = [NSString stringWithFormat:@"Device Token=%@",deviceToken];
NSLog(@"Device Token:%@",str);
//NSLog(@"Device token is called");
//const void *devTokenBytes = [deviceToken bytes];
//NSLog(@"Device Token");
}
- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err {
NSString *str = [NSString stringWithFormat: @"Error: %@", err];
NSLog(@"Error:%@",str);
}
Además, no olvide verificar el estado del sistema en Apple https://developer.apple.com/system-status/ .
Probé todas las soluciones publicadas anteriormente, pero al final la culpa fue porque el servicio APNS no funcionaba. Al día siguiente, todo estaba funcionando nuevamente como se esperaba.
Además, tienes un error tipográfico en tu método de devolución de llamada:
- (void)application:(UIApplication *)appdidRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
Como Rupesh señaló, el nombre del método correcto es:
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
¡Esa es probablemente la razón por la que nunca recibió el token en su caso!
Asegúrese de llamar a su código (actualización de acuerdo con los tipos de notificación compatibles)
[[UIApplication sharedApplication] registerForRemoteNotificationTypes: UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound];
y el perfil de aprovisionamiento está habilitado para APNS. Es posible que deba volver a descargar el perfil de aprovisionamiento después de habilitar APNS. Si tiene problemas y obtiene errores, entonces quizás debería crear un Entitlements.plist y agregar la clave "aps-environment" con el valor "desarrollo" o "producción", dependiendo del tipo de compilación (normalmente este par clave-valor es contenido en el perfil de aprovisionamiento, pero a veces Xcode se mezcla con ellos).
Asegúrese de que su conexión a Internet esté activada. Esto me llevó horas obtener notificaciones de trabajo debido a la conexión a Internet.
Cometí un error y pasé por alto un detalle de implementación que me llevó hasta aquí. Traté de ponerme elegante y pedirle al usuario las Notificaciones Push más adelante en el proceso de incorporación de la aplicación, así que tenía mis registerForRemoteNotificationTypes
, didRegisterForRemoteNotificationsWithDeviceToken
y didFailToRegisterForRemoteNotificationsWithError
todo en una UIView personalizada.
REVISIÓN: el didRegisterForRemoteNotificationsWithDeviceToken
y didFailToRegisterForRemoteNotificationsWithError
deben estar en el UIApplicationDelegate
( YourAppDelegate.m
) para desencadenarse.
parece obvio ahora, je.
Debe llamar al método registerForNotifications desde didFinishLaunchingWithOptions.
func registerForNotifications(){
if #available(iOS 10.0, *) {
let center = UNUserNotificationCenter.current()
center.delegate = self
center.requestAuthorization(options:[.alert,.sound,.badge]) { (granted, error) in
if granted{
UIApplication.shared.registerForRemoteNotifications()
}else{
print("Notification permission denied.")
}
}
} else {
// For iOS 9 and Below
let type: UIUserNotificationType = [.alert,.sound,.badge];
let setting = UIUserNotificationSettings(types: type, categories: nil);
UIApplication.shared.registerUserNotificationSettings(setting);
UIApplication.shared.registerForRemoteNotifications()
}
}
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let token = String(format: "%@", deviceToken as CVarArg).trimmingCharacters(in: CharacterSet(charactersIn: "<>")).replacingOccurrences(of: " ", with: "")
print(token)
}
extension AppDelegate : UNUserNotificationCenterDelegate{
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (_ options: UNNotificationPresentationOptions) -> Void) {
print("Handle push from foreground”)
let info = ((notification.request.content.userInfo as NSDictionary).value(forKey: "aps") as! NSDictionary)
if let type = info.value(forKey: "type") as? Int{
if type == 0 {
// notification received ,Handle your notification here
}
}
}
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
print("Handle push from background or closed")
let info = ((response.notification.request.content.userInfo as NSDictionary).value(forKey: "aps") as! NSDictionary)
if let type = info.value(forKey: "type") as? Int{
if type == 0 {
// notification received ,Handle your notification here
}
}
}
}
En iOS 8 , además de solicitar acceso de notificación push de forma diferente, también debe registrarse de manera diferente.
Solicitar acceso:
if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
// iOS 8
UIUserNotificationSettings* settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:settings];
} else {
// iOS 7 or iOS 6
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
}
Manejar dispositivo registrado:
// New in iOS 8
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
[application registerForRemoteNotifications];
}
// iOS 7 or iOS 6
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSString *token = [[deviceToken description] stringByTrimmingCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:@"<>"]];
token = [token stringByReplacingOccurrencesOfString:@" " withString:@""];
// Send token to server
}
En iOS 8, algunos métodos están en desuso. Siga los pasos a continuación para la compatibilidad con iOS 8
1. Notificación de registro
if([[UIDevice currentDevice] systemVersion].floatValue >= 8.0)
{
UIUserNotificationSettings* notificationSettings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];
}
else
{
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound|UIRemoteNotificationTypeBadge)];
}
2. Agregue nuevos 2 métodos
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
//register to receive notifications
[application registerForRemoteNotifications];
}
//For interactive notification only
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void(^)())completionHandler
{
//handle the actions
if ([identifier isEqualToString:@"declineAction"]){
}
else if ([identifier isEqualToString:@"answerAction"]){
}
}
Nota: más arriba, se requieren dos nuevos métodos en iOS 8 además de didRegisterForRemoteNotificationsWithDeviceToken
y didReceiveRemoteNotification
contrario, no se invocará el método de delegado.
Esto me pasó a mí, porque reinicié y borré todos los datos en el teléfono (quería un teléfono dev para usar). Esto impidió que APN se conectara en absoluto después de volver a configurar el teléfono.
Intenté todo tipo de cosas, pero lo único que lo solucionó fue configurar el teléfono para que funcione con un operador con una nueva tarjeta SIM.
Este enlace ofrece más pistas sobre lo que podría estar sucediendo: https://developer.apple.com/library/ios/technotes/tn2265/_index.html
Dice que APN intenta conectarse preferentemente a través de operadores / torres en lugar de wifi. Quizás el problema también era que algo estaba pasando con el enrutador bloqueando el puerto 5223 en la red wifi, pero lo dudo porque funcionó bien el día previo al cambio global.
Intenta que funcione para mí,
Primer paso
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
En el método anterior, agregue el código siguiente
UIApplication *application = [UIApplication sharedApplication];
if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge
|UIUserNotificationTypeSound
|UIUserNotificationTypeAlert) categories:nil];
[application registerUserNotificationSettings:settings];
}
else {
UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
[application registerForRemoteNotificationTypes:myTypes];
}
Segundo paso
Agregar código siguiente Función
#ifdef __IPHONE_8_0
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
//register to receive notifications
[application registerForRemoteNotifications];
}
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void(^)())completionHandler
{
//handle the actions
if ([identifier isEqualToString:@"declineAction"]){
}
else if ([identifier isEqualToString:@"answerAction"]){
}
}
#endif
Obtendrá Token del dispositivo en la función siguiente
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
para la respuesta detallada por favor remítalo
Espero que esto sea de ayuda para alguien.
Para mí, lo que solucionó fue ir a la configuración de compilación y en la sección de firma de código, seleccionando manualmente la identidad de firma de código y el perfil de aprovisionamiento. Aparentemente, la configuración automática no recogía la correcta y, por lo tanto, la aplicación no estaba debidamente autorizada.
Si agregó push a una ID de aplicación existente, asegúrese de volver a generar sus perfiles de aprovisionamiento. Si no lo hace, el perfil no sabrá si habilitó la inserción de la ID de la aplicación.
Si los perfiles de aprovisionamiento se usan antes para Habilitar y configurar el servicio de notificación push de Apple, deberá volver a descargar los perfiles de provisión nuevamente.
Elimine los perfiles de aprovisionamiento de Xcode Organizer y del iPhone / iPad. Vaya a Settings -> General -> Profiles -> [Your provisioning] -> Remove
.
Instale los nuevos perfiles de aprovisionamiento descargados. Luego, limpie y ejecute el proyecto desde XCode. Ahora debe llamarse a didRegisterForRemoteNotificationsWithDeviceToken
.
Tenga en cuenta que las notificaciones remotas no son compatibles con el simulador. Por lo tanto, si ejecuta su aplicación en el simulador, no se llamará a didRegisterForRemoteNotificationsWithDeviceToken
.
Tengo un punto en esto. Recientemente también enfrento este problema. He hecho todo de acuerdo con la documentación, pero el método de delegado no fue la llamada. Finalmente vi una publicación que decía ese problema con la red. Luego cambié la red y funciona bien. Así que cuídese de la red también porque pocas redes pueden bloquear el APNS.
Tuve el mismo problema: llamar a registerForRemoteNotificationTypes:
invocó ninguna application:didRegisterForRemoteNotificationsWithDeviceToken:
ni application:didFailToRegisterForRemoteNotificationsWithError:
Finalmente resolví este problema con la ayuda de la nota técnica de Apple TN2265 .
Esto es lo que hice:
En primer lugar, verifiqué dos veces que, de hecho, me estoy TN2265 , incluida la verificación de mi perfil de aprovisionamiento para la clave "aps-environment" y la designación del archivo .app propiamente dicho. Lo tenía todo configurado correctamente.
Luego tuve que depurar los mensajes de estado de Push Notification en la consola (debe instalar PersistentConnectionLogging.mobileconfig provisioning profile en su dispositivo y reiniciarlo. Consulte TN2265 en "Observación de los mensajes de estado de inserción"). Noté que el proceso apns inicia un temporizador y calcula una fecha mínima de disparo, lo que me hizo sospechar que el mensaje de confirmación de registro de Push-Notification, que normalmente se presenta en este punto, es suprimido por APNS, como se indica en TN2265:
Restablecimiento de la alerta de permisos de notificaciones automáticas en iOS
La primera vez que se registra una aplicación push para notificaciones push, iOS pregunta al usuario si desea recibir notificaciones para esa aplicación. Una vez que el usuario ha respondido a esta alerta, no se vuelve a presentar a menos que se restaure el dispositivo o la aplicación se haya desinstalado durante al menos un día.
Si desea simular una ejecución por primera vez de su aplicación, puede dejar la aplicación desinstalada por un día. Puede lograr esto último sin tener que esperar un día configurando el reloj del sistema en un día o más, apagando el dispositivo por completo y volviendo a encender el dispositivo.
Por lo tanto, eliminé la aplicación del dispositivo, luego cambié manualmente la fecha del iPhone en Configuración, reinicié el dispositivo y reinstalé la aplicación.
La próxima vez que mi código llamó a registerForRemoteNotificationTypes
, recibió devoluciones de llamada como se esperaba.
Esto resolvió el problema para mí. Espero eso ayude.
Tuve un problema diferente en el que mis callbacks de notificación de inserción fueron secuestrados por las bibliotecas de terceros, que había incluido, a saber, Firebase. Estas bibliotecas activan los métodos de devolución de llamada push para obtener las devoluciones de llamada.
Espero que esto ayude a alguien.
si está cerrado, presione el mensaje de la aplicación,
No se llamará nunca a appdidRegisterForRemoteNotificationsWithDeviceToken
Requisito mínimo para obtener el token de dispositivo:
No es necesario configurar la id. De la aplicación, el aprovisionamiento o el certificado, etc., por lo tanto, no hay ningún conjunto de firmas de código para obtener el método delegado didRegisterForRemoteNotificationsWithDeviceToken llamado.
Acabo de crear un nuevo proyecto de iOS en Xcode 7 para vista única con configuraciones predeterminadas y le di una identificación de paquete aleatorio como com.mycompany.pushtest que no está configurado en el portal Apple Dev.
Con el siguiente código, obtengo el token de mi dispositivo en el método didRegisterForRemoteNotificationsWithDeviceToken en mi iPad con acceso a internet a WIFI. Mi dispositivo está conectado y solo estoy ejecutando la aplicación directamente desde xcode y viendo los valores en la consola de xcode.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if ([application respondsToSelector:@selector(registerUserNotificationSettings:)])
{
UIUserNotificationType userNotificationTypes = (UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound);
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:userNotificationTypes categories:nil];
[application registerUserNotificationSettings:settings];
[application registerForRemoteNotifications];
}
else
{
// Register for Push Notifications, if running iOS version < 8
[application registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound)];
}
return YES;
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
NSLog(@"Error: %@", error.description);
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSLog(@"didRegisterForRemoteNotificationsWithDeviceToken: %@", deviceToken);
}
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
NSLog(@"NotificationSettings: %@", notificationSettings);
}
-(BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions{ //Overridepointforcustomizationafterapplicationlaunch.
//Addtheviewcontroller’sviewtothewindowanddisplay. [windowaddSubview:viewController.view]; [windowmakeKeyAndVisible];
NSLog(@”Registering for push notifications...”);
[[UIApplication sharedApplication]
registerForRemoteNotificationTypes: (UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeBadge |
UIRemoteNotificationTypeSound)];
returnYES;
}
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
}
NSString *str = [NSString stringWithFormat:@”Device Token=%@”,deviceToken];
NSLog(@”%@”, str);
- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err {
NSString *str = [NSString stringWithFormat: @”Error: %@”, err]; NSLog(@”%@”, str);
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
}
for (id key in userInfo) { NSLog(@”key: %@, value: %@”, key, [userInfo objectForKey:key]);
}