远程通知iOS 8


Answers:


180

阅读UIApplication.h中的代码。

您将知道该怎么做。

第一:

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

像这样添加代码

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,请尝试使用此代码

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的提醒)


第二:

添加此功能

#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

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

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

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

4
这个。如此令人恐惧的是,Apple无法更新其文档UIUserNotificationSettingsUIApplication谈论iOS 8的要求。它被掩藏在其API差异中。
Hyperbole 2014年

27
这将在iOS 8以下的iOS版本上崩溃。#ifdef是一个COMPILER函数,在编译时进行评估。您仍然需要运行时检查!
Dan VanWinkle 2014年

4
使用此宏检查iOS 8:#define isAtLeastiOS8([[[[UIDevice currentDevice] systemVersion] floatValue]> = 8.0)。__IPHONE_8_0不是很好的检查方法,因为您希望此代码也继续在以后的版本中运行。
er0 2014年

2
就是说,在这种情况下#ifdef是不必要的,除非您的团队同时使用Xcode 5和if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {Xcode6 。相反,您应该像zeiteisen所做的那样进行检查。
dmur

6
已弃用的枚举UIRemoteNotificationType的一点点校正:NS_ENUM_DEPRECATED_IOS(3_0,8_0,“将UIUserNotificationType用于用户通知,而registerForRemoteNotifications用于接收远程通知。”); 因此,对于iOS 8及更高版本,您必须使用UIUserNotificationTypeBadge,UIUserNotificationTypeSound,UIUserNotificationTypeAlert。(新版本为UIUserNotificationType,旧版本为UIRemoteNotificationType)。<UIKit / UIApplication.h>和<UIKit / UIUserNotificationSettings.h>中定义的枚举
KepPM

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];
}

并在应用程序委托中添加

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

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

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

如果启用了任何通知类型,请为您的应用检查设置。如果没有,您将不会获得设备令牌。

您现在可以通过以下方式获取静默通知

aps {
content-available: 1
}

在通知有效载荷中

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

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

此代码应寻求许可。

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


1
谢谢你的帮助OS8 can receive silent notifications without asking for permission。那让我发疯,这是我发现唯一有帮助的地方!
sbauch 2015年

@zeiteisen,在你第一次if声明中,你应该使用UIUserNotificationTypeSound替代UIRemoteNotificationTypeSound,因为UIRemoteNotificationType在iOS的8弃用
坦纳Semerad

有人可以解释为什么仅在启用“后台应用刷新”时调用带有令牌的回调吗?我虽然应该在启用“推送通知”权限时调用它
guilherme.minglini

15

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

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

1

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

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服务器返回的设备令牌:

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

1

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

UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIRemoteNotificationTypeBadge

应该更“正确”

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

这些标志有相同的位掩码值和这就是为什么既会工作,但UIUserNotificationSettings要求UIUserNotificationType没有UIRemoteNotificationType

除此之外,我会打电话

[application registerUserNotificationSettings:settings];

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

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

有什么不同?
弗拉基米尔·斯塔吉洛夫

1
UIUserNotificationTypeBadge和UIRemoteNotificationTypeBadge是相同的位掩码,但表示不同的内容=)
Ilker Baltaci 2014年

0

我想保持这种方法向后兼容的更好的方法是,这对我来说很有效,希望对您有用。也很容易理解。

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)];
    }

0
UIUserNotificationType types = UIUserNotificationTypeBadge |
    UIUserNotificationTypeSound | UIUserNotificationTypeAlert;

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

    [[UIApplication sharedApplication] registerUserNotificationSettings:mySettings];

    [application registerForRemoteNotifications];
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.