远程通知iOS 8

qua*_*ang 76 objective-c apple-push-notifications ios8

如何在iOS 8中获取设备令牌以进行远程通知?我所使用的方法didRegisterForRemoteNotificationsWithDeviceTokenAppDelegate在IOS <8,并且它返回的设备令牌.但在iOS 8中,它没有.

Mad*_*dao 180

阅读UIApplication.h中的代码.

你会知道怎么做.

第一:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
Run Code Online (Sandbox Code Playgroud)

像这样添加代码

if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
#ifdef __IPHONE_8_0
  UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeAlert 
      | UIUserNotificationTypeBadge 
      | UIUserNotificationTypeSound) categories:nil];
  [application registerUserNotificationSettings:settings];
#endif
} else {
  UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
  [application registerForRemoteNotificationTypes:myTypes];
}
Run Code Online (Sandbox Code Playgroud)

如果您不同时使用Xcode 5和Xcode 6,请尝试此代码

if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
  UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIRemoteNotificationTypeBadge
      |UIRemoteNotificationTypeSound
      |UIRemoteNotificationTypeAlert) categories:nil];
  [application registerUserNotificationSettings:settings];
} else {
  UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
  [application registerForRemoteNotificationTypes:myTypes];
}
Run Code Online (Sandbox Code Playgroud)

(感谢@zeiteisen @dmur的提醒)


第二:

添加此功能

#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
Run Code Online (Sandbox Code Playgroud)

你可以获得deviceToken

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
Run Code Online (Sandbox Code Playgroud)

如果它仍然不起作用,使用此功能和NSLog 错误

-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
Run Code Online (Sandbox Code Playgroud)

  • 这将在iOS 8以下的iOS版本上崩溃.#ifdef是一个COMPILER函数,在编译时进行评估.你还需要运行时检查! (27认同)
  • 已弃用的枚举UIRemoteNotificationType的小位更正:NS_ENUM_DEPRECATED_IOS(3_0,8_0,"使用UIUserNotificationType进行用户通知,使用registerForRemoteNotifications接收远程通知."); 因此,对于iOS 8及更高版本,您必须使用UIUserNotificationTypeBadge,UIUserNotificationTypeSound,UIUserNotificationTypeAlert.(新版本的UIUserNotificationType,旧版本的UIRemoteNotificationType).<UIKit/UIApplication.h>和<UIKit/UIUserNotificationSettings.h>中定义的枚举 (6认同)
  • 这个.从理论上说,苹果公司未能更新他们的文档"UIUserNotificationSettings"或"UIApplication",谈论iOS 8是如何需要的.它隐藏在他们的API差异中. (4认同)
  • 使用此宏来检查iOS 8:#define isAtLeastiOS8([[[[[UIDevice currentDevice] systemVersion] floatValue]> = 8.0).__IPHONE_8_0不是一个好检查,因为您希望此代码也继续在未来版本上运行. (4认同)
  • 也就是说,在这种情况下,#ifdef是不必要的,除非你的团队同时使用Xcode 5和Xcode 6.相反,你应该做一个`if([application respondsToSelector:@selector(registerUserNotificationSettings :)]){`check,as zeiteisen在他的回答中. (2认同)

zei*_*sen 75

注册iOS 8并继续支持旧版本的方法

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];
}
Run Code Online (Sandbox Code Playgroud)

并在应用程序委托添加

- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
    [application registerForRemoteNotifications];
}
Run Code Online (Sandbox Code Playgroud)

iOS8可以在未经许可的情况下收到静默通知.打电话 - (void)registerForRemoteNotifications.在此之后 application:didRegisterForRemoteNotificationsWithDeviceToken:将被调用

注意:仅当应用程序已成功注册具有以下功能的用户通知或启用了后台应用程序刷新时,才会调用带有令牌的回调.

如果启用了任何通知类型,请检查您的应用程序设置.如果没有,您将无法获得设备令牌.

您现在可以使用获取静默通知

aps {
content-available: 1
}
Run Code Online (Sandbox Code Playgroud)

在通知有效负载中

但出现的通知仍需要许可.呼叫

UIUserNotificationType types = UIUserNotificationTypeSound | UIUserNotificationTypeBadge | UIUserNotificationTypeAlert;
UIUserNotificationSettings *notificationSettings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
[application registerUserNotificationSettings:notificationSettings];
Run Code Online (Sandbox Code Playgroud)

此代码应该请求许可.

您现在应该准备好获取推送通知了


Kyl*_*egg 15

在我的情况下,我已经进行了必要的更新以请求iOS 7和iOS 8的推送通知访问,但是当iOS 8用户授予访问权限时,我没有实现新的回调.我需要将此方法添加到我的app委托.

- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
    [application registerForRemoteNotifications];
}
Run Code Online (Sandbox Code Playgroud)