为什么不调用RegisterForRemoteNotificationsWithDeviceToken
我正在做一个应用程序,我想实施苹果推送通知服务。 我正在按照本教程中的步骤进行操作。
但是,仍然没有调用这些方法。 我不知道是什么原因造成的问题。 任何人都可以帮我吗?
- (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); }
我有同样的问题:调用registerForRemoteNotificationTypes:
既不调用application:didRegisterForRemoteNotificationsWithDeviceToken:
也不是application:didFailToRegisterForRemoteNotificationsWithError:
我最终在苹果技术说明TN2265的帮助下解决了这个问题。
这就是我所做的:
首先,我仔细检查了我确实注册了推送通知 ,包括validation“aps-environment”密钥的供应configuration文件以及.app文件本身的密码设置。 我已经把它设置正确。
然后,我必须在控制台中debugging推送通知状态消息(您需要在设备上安装PersistentConnectionLogging.mobileconfig 预configurationconfiguration文件并重新启动它,请参阅“观察推送状态消息”下的TN2265 )。 我注意到,apns进程启动一个计时器并计算一个最小的启动date,这使我怀疑在这一点上通常出现的Push-Notification注册确认消息被APNS所抑制,如TN2265所示:
在iOS上重置推送通知权限警报
当推送应用程序第一次注册推送通知时,iOS会询问用户是否希望接收该应用程序的通知。 一旦用户对此警报作出响应,除非设备已恢复或应用程序已卸载至less一天,否则不会再次显示。
如果您想模拟首次运行您的应用,则可以将该应用卸载一天。 您可以实现后者,而无需等待一天,方法是将系统时钟设置为一天或更长时间,完全closures设备,然后重新打开设备。
所以,我从设备中删除了应用程序,然后在“设置”中手动更改了iPhone的date,重新启动了设备,然后重新安装了应用程序。
下一次我的代码调用registerForRemoteNotificationTypes
,它收到了预期的callback。
这为我解决了这个问题。 希望它有帮助。
在iOS 8中,某些方法已被弃用。 按照以下步骤进行iOS 8兼容性
1.注册通知
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.添加新的2个方法
- (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"]){ } }
注意:除了didRegisterForRemoteNotificationsWithDeviceToken
和didReceiveRemoteNotification,iOS 8还需要上述两个新方法。否则委托方法将不会被调用。
请参阅: 远程通知iOS 8
在iOS 8中 ,除了以不同的方式请求推送通知访问外,还需要以不同方式注册。
申请进入:
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)]; }
处理注册的设备:
// 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 }
确保您拨打您的代码(根据支持的通知种类进行更新)
[[UIApplication sharedApplication] registerForRemoteNotificationTypes: UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound];
并且configuration文件是APNS启用的。 启用APNS后,您可能需要重新下载configuration文件。 如果你有麻烦,你会得到错误,那么也许你应该创build一个Entitlements.plist,并根据构build的types添加值为“development”或“production”的关键字“aps-environment”(通常这个键值对是包含在configuration文件中,但有时Xcode与他们混淆)。
请记住,模拟器不支持远程通知。 因此,如果您在模拟器中运行您的应用程序,则不会调用didRegisterForRemoteNotificationsWithDeviceToken
。
如果之前使用configurationconfiguration文件来启用和configurationApple推送通知服务,则需要重新下载configurationconfiguration文件。
从Xcode Organizer和iPhone / iPad中删除configuration文件。 进入Settings -> General -> Profiles -> [Your provisioning] -> Remove
。
安装新下载的configuration文件。 然后清理并从XCode运行该项目。 现在应该调用didRegisterForRemoteNotificationsWithDeviceToken
。
我犯了一个错误,忽略了引导我到这里的实现细节。 我试图得到幻想,稍后在应用程序didRegisterForRemoteNotificationsWithDeviceToken
过程中询问用户推送通知,所以我有我的registerForRemoteNotificationTypes
, didRegisterForRemoteNotificationsWithDeviceToken
和didFailToRegisterForRemoteNotificationsWithError
所有在自定义UIView。
FIX: didRegisterForRemoteNotificationsWithDeviceToken
和didFailToRegisterForRemoteNotificationsWithError
需要在UIApplicationDelegate
( YourAppDelegate.m
)中被触发。
现在看来很明显,嘿。
确保您的互联网连接已开启。 由于互联网连接,我花了几个小时才得到工作通知。
如果您已经添加了推送到现有的应用程序ID,请确保您重新生成您的供应configuration文件。 如果你不这样做,那么configuration文件将不会知道你启用了App ID。
-(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]); }
获取设备令牌的最低要求:
无需configuration应用程序ID,供应或证书等,因此没有代码签名设置来获取委托方法didRegisterForRemoteNotificationsWithDeviceToken调用。
我刚刚在Xcode 7中为默认设置的单一视图创build了一个新的iOS项目,并给出了一个随机的bundle id,例如com.mycompany.pushtest,它在apple dev portal中没有configuration。
通过以下代码,我可以在我的iPad上通过互联网访问WIFI获取我的设备令牌,位于didRegisterForRemoteNotificationsWithDeviceToken方法中。 我的设备已连接,我只是直接从xcode运行应用程序,并在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
在上面的方法中添加以下代码
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]; }
第二步
添加以下代码function
#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
您将在下面的function中获得设备令牌
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
详细的回答请参考这个
希望这是对某个人的帮助。
这发生在我身上,因为我重置并删除了手机上的所有数据(想要开发手机使用)。 这样在再次设置电话之后,就完全阻止了APN的连接。
我尝试了各种各样的东西,但是唯一解决这个问题的就是将手机设置为与新SIM卡下的运营商合作。
这个链接提供了更多关于可能发生的事情的提示: https : //developer.apple.com/library/ios/technotes/tn2265/_index.html
它说,APN试图优先通过运营商/塔而不是无线连接。 也许这个问题也是在wifinetworking上的路由器阻塞端口5223上发生的,但是我怀疑它是因为在全局复位发生之前的前一天它工作正常。
我对此有一个观点。最近我也面临这个问题。我根据文档做了所有事情,但委托方法并没有调用。最后,我看到一个职位说networking的问题,然后我改变了networking,它工作正常。所以,关心networking也是因为很less的networking可以阻止APNS。
对我来说,解决了这个问题就是在构build设置和代码签名部分,手动select代码签名标识和configuration文件。 很明显,自动设置并不是正确的,因此应用程序没有得到正确的授权。
如果closures应用程序的推送消息,
appdidRegisterForRemoteNotificationsWithDeviceToken永远不会被调用
另外,请不要忘记在Apple https://developer.apple.com/system-status/上检查系统状态。;
我尝试了上述所有的解决scheme,但最终的错误是因为APNS服务停机! 第二天,所有人都按预期再次工作。
另外,你的callback方法有一个错字:
- (void)application:(UIApplication *)appdidRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
Rupesh指出正确的方法名称是:
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
这可能就是为什么你从来没有收到你的情况令牌!
您需要从didFinishLaunchingWithOptions中调用registerForNotifications方法。
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 } } } }
我遇到了一个不同的问题,那就是我的推送通知callback被第三方库(包括Firebase)劫持了。 这些库swizzle推送通知callback方法来获取callback。
希望这有助于某人。