关于Objective C:远程通知iOS 8

Remote Notification iOS 8

如何在iOS 8中获取用于远程通知的设备令牌?
我在iOS <8中的AppDelegate中使用了方法didRegisterForRemoteNotificationsWithDeviceToken,它返回了设备令牌。但是在iOS 8中却没有。


阅读UIApplication.h中的代码。

您将知道该怎么做。

第一位:

1
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

添加这样的代码

1
2
3
4
5
6
7
8
9
10
11
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];
}

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

1
2
3
4
5
6
7
8
9
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];
}

(感谢@zeiteisen @dmur的提醒)

第二个:

添加此功能

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#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

您可以在

中获取deviceToken

1
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken

如果仍然无法正常工作,请使用此功能,并通过NSLog记录错误

1
-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error


注册iOS 8并继续支持较早版本的方式

1
2
3
4
5
6
7
8
9
10
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];
}

,然后在应用程序委托中添加

1
2
3
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
    [application registerForRemoteNotifications];
}

iOS8无需征求许可即可接收静默通知。称呼
- (void)registerForRemoteNotifications。在此之后application:didRegisterForRemoteNotificationsWithDeviceToken:将被称为

注意:仅当应用程序已使用下面的功能成功注册了用户通知时,或者启用了"后台应用程序刷新",才调用带有令牌的回调。

检查是否为您的应用设置了任何通知类型。否则,您将不会获得设备令牌。

您现在可以通过

获取静默通知

1
2
3
aps {
content-available: 1
}

通知有效负载中的

但是出现的通知仍需要许可。致电

1
2
3
UIUserNotificationType types = UIUserNotificationTypeSound | UIUserNotificationTypeBadge | UIUserNotificationTypeAlert;
UIUserNotificationSettings *notificationSettings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
[application registerUserNotificationSettings:notificationSettings];

此代码应寻求许可。

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


就我而言,我已经进行了必要的更新,以请求对iOS 7和iOS 8的推送通知访问,但是当iOS 8用户授予访问权限时,我没有实现新的回调。我需要将此方法添加到我的应用程序委托中。

1
2
3
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
    [application registerForRemoteNotifications];
}

Madao(https://stackoverflow.com/a/24488562/859742)的答案是正确的,但是....

1
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIRemoteNotificationTypeBadge

应该更多"正确"

1
UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert) categories:nil];

那些标志具有相同的位掩码值,这就是为什么两个标志都起作用但UIUserNotificationSettings要求UIUserNotificationType而不是UIRemoteNotificationType的原因。

除此之外,我会称呼

1
[application registerUserNotificationSettings:settings];

AppDelegate方法中(取决于授予的权限),

1
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings


如果您使用Xamarin.iOS来构建移动应用程序,则可以使用此代码段来请求推送通知注册

1
2
3
4
5
6
7
8
9
10
11
if (UIDevice.CurrentDevice.CheckSystemVersion(8,0))
{
    UIUserNotificationType userNotificationTypes = UIUserNotificationType.Alert | UIUserNotificationType.Badge | UIUserNotificationType.Sound;
    UIUserNotificationSettings settings = UIUserNotificationSettings.GetSettingsForTypes(userNotificationTypes, null);
    UIApplication.SharedApplication.RegisterUserNotificationSettings(settings);
}
else
{
    UIRemoteNotificationType notificationTypes = UIRemoteNotificationType.Alert | UIRemoteNotificationType.Badge | UIRemoteNotificationType.Sound;
    UIApplication.SharedApplication.RegisterForRemoteNotificationTypes(notificationTypes);
}

此外,您将需要覆盖DidRegisterUserNotificationSettings方法来获取从APNS服务器返回的设备令牌:

1
2
3
4
public override void DidRegisterUserNotificationSettings(UIApplication application, UIUserNotificationSettings notificationSettings)
{
    application.RegisterForRemoteNotifications();
}

1
2
3
4
5
6
7
8
9
UIUserNotificationType types = UIUserNotificationTypeBadge |
    UIUserNotificationTypeSound | UIUserNotificationTypeAlert;

    UIUserNotificationSettings *mySettings =
    [UIUserNotificationSettings settingsForTypes:types categories:nil];

    [[UIApplication sharedApplication] registerUserNotificationSettings:mySettings];

    [application registerForRemoteNotifications];

我认为保持这种向后兼容性的更好的方法是使用这种方法,它正在为我的情况工作,希望对您有用。也很容易理解。

1
2
3
4
5
6
7
8
9
10
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
    {
        [[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    }
    else
    {
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
         (UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert)];
    }