【发布时间】:2014-06-14 04:40:35
【问题描述】:
如何在 iOS 8 中获取用于远程通知的设备令牌?
我在 iOS AppDelegate 中使用了 didRegisterForRemoteNotificationsWithDeviceToken 方法,它返回了设备令牌。但在 iOS 8 中,它不会。
【问题讨论】:
标签: objective-c ios8 apple-push-notifications
如何在 iOS 8 中获取用于远程通知的设备令牌?
我在 iOS AppDelegate 中使用了 didRegisterForRemoteNotificationsWithDeviceToken 方法,它返回了设备令牌。但在 iOS 8 中,它不会。
【问题讨论】:
标签: objective-c ios8 apple-push-notifications
你会知道怎么做的。
第一:
- (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 in
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
如果还是不行,使用这个函数并 NSLog error
-(void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
【讨论】:
UIUserNotificationSettings 或 UIApplication 文档,谈论 iOS 8 的要求。相反,它隐藏在他们的 API 差异中。
if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]) { 检查,就像 zeiteisen 在他的回答中所做的那样。
注册 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];
此代码应请求许可。
您现在应该准备好接收推送通知了
【讨论】:
OS8 can receive silent notifications without asking for permission 位。这让我发疯了,这是我唯一发现有帮助的地方!
if 语句中,您应该使用UIUserNotificationTypeSound 而不是UIRemoteNotificationTypeSound,因为UIRemoteNotificationType 在iOS 8 中已被弃用。
在我的例子中,我已经进行了必要的更新来请求 iOS 7 和 iOS 8 的推送通知访问权限,但是当 iOS 8 用户授予访问权限时,我还没有实现新的回调。我需要将此方法添加到我的应用委托中。
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
[application registerForRemoteNotifications];
}
【讨论】:
如果您使用 Xamarin.iOS 构建您的移动应用程序,您可以使用此代码的 sn-p 请求推送通知注册
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();
}
【讨论】:
麻道(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
【讨论】:
我认为保持向后兼容性的更好方法是我们可以采用这种方法,它适用于我的情况,希望对你有用。也很容易理解。
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)];
}
【讨论】:
UIUserNotificationType types = UIUserNotificationTypeBadge |
UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
UIUserNotificationSettings *mySettings =
[UIUserNotificationSettings settingsForTypes:types categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:mySettings];
[application registerForRemoteNotifications];
【讨论】: