在iOS 8中获取设备令牌

时间:2014-06-26 08:44:51

标签: ios ios8

我需要设备令牌才能在我的应用中实现推送通知。
如何获取设备令牌,因为didRegisterForRemoteNotificationsWithDeviceToken方法在iOS 8上不起作用。 我在app delegate中尝试了这个代码,但它没有给我设备令牌。

    [[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
    [[UIApplication sharedApplication] registerForRemoteNotifications];

8 个答案:

答案 0 :(得分:56)

阅读UIApplication.h中的代码。

你会知道怎么做。

首先:

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

像这样添加代码

#ifdef __IPHONE_8_0
  //Right, that is the point
    UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIRemoteNotificationTypeBadge
|UIRemoteNotificationTypeSound
|UIRemoteNotificationTypeAlert) categories:nil];
    [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
#else
    //register to receive notifications
    UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound;
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:myTypes];
#endif

如果您不同时使用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

答案 1 :(得分:11)

在旧版iOS版本崩溃的情况下,对@Madao的回复进行小验证:

#ifdef __IPHONE_8_0
if(NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_7_1) {
    UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge|UIUserNotificationTypeSound|UIUserNotificationTypeAlert) categories:nil];
    [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
}
#endif

UIRemoteNotificationType myTypes = UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound |     UIRemoteNotificationTypeNewsstandContentAvailability;
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:myTypes];

__IPHONE_8_0宏所做的只是允许您在旧版本的xCode / iOS中编译,您不会收到编译错误或警告,但在iOS 7或更低版​​本的设备上运行代码会导致崩溃。

答案 2 :(得分:3)

在iOS8 +中获取设备令牌

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//This code will work in iOS 8.0 xcode 6.0 or later
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0)
{
    [[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];
    [[UIApplication sharedApplication] registerForRemoteNotifications];
}
else
{
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes: (UIRemoteNotificationTypeNewsstandContentAvailability| UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
}
return YES;
}

- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{
NSString* deviceToken = [[[[deviceToken description]
                         stringByReplacingOccurrencesOfString: @"<" withString: @""]
                         stringByReplacingOccurrencesOfString: @">" withString: @""]
                         stringByReplacingOccurrencesOfString: @" " withString: @""] ;
NSLog(@"Device_Token     -----> %@\n",deviceToken);
}

答案 3 :(得分:1)

2020解决方案

六个步骤,

1。库

enter image description here

2。添加到AppDelegate

// APNs:

func application(_ application: UIApplication,
      didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    print(">> getting an APNs token works >>\(deviceToken)<<")
    let tokenAsText = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
}

func application(_ application: UIApplication,
      didFailToRegisterForRemoteNotificationsWithError error: Error) {
    print(">> error getting APNs token  >>\(error)<<")
}

3。在您的应用中

例如,用户登录后

import UserNotifications

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)
    askNotifications()
}

func askNotifications() {
    let n = UNUserNotificationCenter.current()
    n.requestAuthorization(options: [.alert, .sound, .badge]) {
        granted, error in
        print("result \(granted) \(String(describing: error))")

        guard granted else {
            print("not granted!")
            return
        }

        DispatchQueue.main.async {
            UIApplication.shared.registerForRemoteNotifications()
        }
    }
}

4。功能标签

执行 三个

enter image description here

当心旧文章:那里不再有“开关”。

5。系留电话,没有模拟器

它将 在模拟器中运行。必须是电话

enter image description here

系留电话很好,控制台可以正常工作

6。最后... WIFI DANCE

具有100%的可重复性,从2020年起,您必须执行以下操作:

    从共享电话中
  1. 完全擦除应用
  2. 构建到手机并从Xcode运行 ( 绝对 将无效)
  3. 强制退出应用程序
  4. 从共享电话中
  5. 完全擦除应用
  6. 同时关闭wifi /蜂窝
  7. 构建到手机并从Xcode运行 (显然无法正常工作)
  8. 强制退出应用程序

然后完全按照以下顺序进行:

    从共享电话中
  1. 完全擦除应用
  2. 打开连接(无论是wifi还是手机都可以-没问题)
  3. 构建手机并从Xcode运行

现在可以使用。 (并且将从这里开始工作。)

WIFI DANCE只是这些怪异的Apple产品之一。他们还没有修复它(Xcode 11.3)。实际上,它已经变得“ 100%可重复”:您必须执行WIFI DANCE。

答案 4 :(得分:0)

除了对此问题的其他居高临下的答案之外,对于已实施所有必需委托方法的知情开发人员而言,可能出现此问题的最可能原因是他们使用通配符配置文件< / strong>(为什么不能?这样可以轻松创建和测试开发应用程序!)

在这种情况下,您可能会看到错误Error Domain=NSCocoaErrorDomain Code=3000 "no valid 'aps-environment' entitlement string found for application"

为了测试通知,您实际上必须回到2000年末,登录developer.apple.com,并设置特定于应用程序的配置文件,并启用推送通知。

  1. 创建与您应用的捆绑包标识符对应的应用ID。一定要检查&#34;推送通知&#34; (目前是第二个选项)。
  2. 为该App ID创建配置文件。
  3. 完成我们所有人都想忘记的其他可怕的配置步骤。
  4. 利润!

答案 5 :(得分:0)

在您的开发者帐户中,确保在应用程序ID中正确设置推送通知,然后您需要重新生成并下载配置文件。我的问题是我下载了配置文件,但xcode运行的是错误的。要解决此问题,请转到“目标构建设置”,向下滚动到“代码签名”,在“配置文件”部分下,确保使用的是与您生成的配置文件名相匹配的正确配置文件(如果您有选项,则应该有一个下拉列表安装了多个)。

答案 6 :(得分:0)

@pdoa答案绝对正确。请注意它无法在模拟器中使用

在这种情况下

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

时出现错误REMOTE_NOTIFICATION_SIMULATOR_NOT_SUPPORTED_NSERROR

答案 7 :(得分:0)

这是解决方案。

在applicationDidFinishLaunchingWithOptions:

{

 UIUserNotificationType types = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
    UIUserNotificationSettings *mySettings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
    [[UIApplication sharedApplication] registerUserNotificationSettings:mySettings];
}


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


- (void)application:(UIApplication*)application didFailToRegisterForRemoteNotificationsWithError:(nonnull NSError *)error
{
    NSLog(@" Error while registering for remote notifications: %@", error);
}

- (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(nonnull NSData *)deviceToken
{
  NSLog(@"Device Token is : %@", deviceToken);
}