【问题标题】:Get device token for push notification获取推送通知的设备令牌
【发布时间】:2012-02-06 14:18:25
【问题描述】:

我正在处理推送通知。我编写了以下代码来获取设备令牌。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
    // Override point for customization after application launch.

    // Add the view controller's view to the window and display.
    [self.window addSubview:viewController.view];
    [self.window makeKeyAndVisible];

    NSLog(@"Registering for push notifications...");    
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
     (UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];

    return YES;
}

- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { 
    NSString *str = [NSString stringWithFormat:@"Device Token=%@",deviceToken];
    NSLog(@"This is device token%@", deviceToken);
}

- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err { 
    NSString *str = [NSString stringWithFormat: @"Error: %@", err];
    NSLog(@"Error %@",err);    
}

我能够在设备上成功运行应用程序,但无法在控制台上获取设备 ID。

我对认证和配置文件没有任何问题。

【问题讨论】:

  • 你关注all the steps了吗?如果您在认证和提供以及代码方面没有任何问题,那么您一定是犯了一些小错误。就像..告诉我,您是否在与您的系统连接相同的真实设备上运行该应用程序?您是否还注意到您是否在控制台日志中获取设备令牌? Have you enable Push notification in iPhone?
  • 我无法在控制台日志中获取设备令牌。
  • 我在真机上运行应用程序没有任何错误。
  • 您是否按照 iPhone 上的链接启用了 APNS?
  • 是的,我启用了 APNS..但是设备令牌无法在 cosole 上获取

标签: ios iphone push-notification apple-push-notifications appdelegate


【解决方案1】:

注意:以下解决方案不再适用在 iOS 13+ 设备上 - it will return garbage data

请改用以下代码:

+ (NSString *)hexadecimalStringFromData:(NSData *)data
{
  NSUInteger dataLength = data.length;
  if (dataLength == 0) {
    return nil;
  }

  const unsigned char *dataBuffer = (const unsigned char *)data.bytes;
  NSMutableString *hexString  = [NSMutableString stringWithCapacity:(dataLength * 2)];
  for (int i = 0; i < dataLength; ++i) {
    [hexString appendFormat:@"%02x", dataBuffer[i]];
  }
  return [hexString copy];
}

在 iOS 13 之前有效的解决方案:

目标-C

- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken 
{
    NSString *token = [[deviceToken description] stringByTrimmingCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:@"<>"]];
    token = [token stringByReplacingOccurrencesOfString:@" " withString:@""];
    NSLog(@"this will return '32 bytes' in iOS 13+ rather than the token", token);
} 

斯威夫特 3.0

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)
{
    let tokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})
    print("this will return '32 bytes' in iOS 13+ rather than the token \(tokenString)")
}

【讨论】:

  • 那么请检查您的配置文件,它应该是您为推送通知创建 ssl 证书的应用 ID。
  • 你需要将代码添加到AppDelegate文件@jagzzz
  • 对于那些对用 Swift 编写的代码示例感兴趣的人:gist.github.com/sawapi/a7cee65e4ad95578044d
  • 小心,使用“描述”属性不再有效:stackoverflow.com/questions/39495391/…
  • @codester 我已经使用 Xcode 10.3 上传了我的构建并且它是实时的。根据您的说法,Objective C 方法将继续使用 XCode 11,但我在我们的数据库中可以看到它显示的是数据长度,而不是正确的 apns 令牌字符串。所以我只想知道,这取决于 Xcode 版本还是 iOS 版本(即 13.*)?
【解决方案2】:

要获得令牌设备,您可以通过一些步骤

1) 为 Developer Certification 和 Distribute Certification 启用 APNS(Apple Push Notification Service),然后重新下载这两个文件。

2) 重新下载 Developer Provisioning 和 Distribute Provisioning 文件。

3) 在 Xcode 界面中:为 PROJECT 和 TARGETS 设置配置,两个文件配置已下载。

4) 最后需要在 AppDelegate 文件中添加如下代码来获取 Token Device (注意:在真机上运行应用程序)。

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    
     [self.window addSubview:viewController.view];
     [self.window makeKeyAndVisible];

     NSLog(@"Registering for push notifications...");    
     [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
 (UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
     return YES;
}

- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { 
     NSString *str = [NSString stringWithFormat:@"Device Token=%@",deviceToken];
     NSLog(@"%@", str);
}

- (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err { 
     NSString *str = [NSString stringWithFormat: @"Error: %@", err];
     NSLog(@"%@",str);
}

【讨论】:

    【解决方案3】:

    使用description,正如许多这些答案所暗示的那样,wrong approach - 即使你让它工作,它也会在 iOS 13+ 中中断。

    相反,您应该确保使用实际的二进制数据,而不仅仅是对其进行描述。 Andrey Gagan 很好地解决了 Objective C 解决方案,但幸运的是它在 swift 中要简单得多:

    Swift 4.2 适用于 iOS 13+

    // credit to NSHipster (see link above)
    // format specifier produces a zero-padded, 2-digit hexadecimal representation
    let deviceTokenString = deviceToken.map { String(format: "%02x", $0) }.joined()
    

    【讨论】:

      【解决方案4】:

      Objective C for iOS 13+,感谢 Wasif Saood 的回答

      将以下代码复制并粘贴到 AppDelegate.m 以打印设备 APN 令牌。

      - (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
      {
        NSUInteger dataLength = deviceToken.length;
        if (dataLength == 0) {
          return;
        }
        const unsigned char *dataBuffer = (const unsigned char *)deviceToken.bytes;
        NSMutableString *hexString  = [NSMutableString stringWithCapacity:(dataLength * 2)];
        for (int i = 0; i < dataLength; ++i) {
          [hexString appendFormat:@"%02x", dataBuffer[i]];
        }
        NSLog(@"APN token:%@", hexString);
      }
      

      【讨论】:

        【解决方案5】:

        以下代码用于检索设备令牌。

            // Prepare the Device Token for Registration (remove spaces and < >)
            NSString *devToken = [[[[deviceToken description] 
                                    stringByReplacingOccurrencesOfString:@"<"withString:@""] 
                                   stringByReplacingOccurrencesOfString:@">" withString:@""] 
                                  stringByReplacingOccurrencesOfString: @" " withString: @""];
        
        
            NSString *str = [NSString 
                             stringWithFormat:@"Device Token=%@",devToken];
            UIAlertView *alertCtr = [[[UIAlertView alloc] initWithTitle:@"Token is " message:devToken delegate:self cancelButtonTitle:nil otherButtonTitles: nil] autorelease];
            [alertCtr show];
            NSLog(@"device token - %@",str);
        

        【讨论】:

        • 这从来都不是正确的解决方案。永远不要以description 为基础。
        【解决方案6】:

        Wasif 答案的 Swift 版本:

        Swift 2.x

        var token = deviceToken.description.stringByTrimmingCharactersInSet(NSCharacterSet(charactersInString: "<>"))
        token = token.stringByReplacingOccurrencesOfString(" ", withString: "")
        print("Token is \(token)")
        

        Swift 3 更新

        let deviceTokenString = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
        

        【讨论】:

        • 永远不要在二进制数据上使用description(请参阅任何其他答案)
        【解决方案7】:

        从 iOS 13 开始,Apple 更改了 [deviceToken description]output。现在是这样的{length=32,bytes=0x0b8823aec3460e1724e795cba45d22e8...af8c09f971d0dabc},这对于设备令牌是不正确的。

        我建议使用此代码 sn-p 来解决问题:

        + (NSString *)stringFromDeviceToken:(NSData *)deviceToken {
            NSUInteger length = deviceToken.length;
            if (length == 0) {
                return nil;
            }
            const unsigned char *buffer = deviceToken.bytes;
            NSMutableString *hexString  = [NSMutableString stringWithCapacity:(length * 2)];
            for (int i = 0; i < length; ++i) {
                [hexString appendFormat:@"%02x", buffer[i]];
            }
            return [hexString copy];
        }
        

        适用于 iOS13 及更低版本。

        【讨论】:

        • 仅供参考 - 任何曾经使用过description 的答案都是错误的。这只是将令牌转换为字符串的一种可能解决方案。一个更简单的解决方案是使用标准 base64 编码将NSData 转换为NSString
        【解决方案8】:

        如果您仍然没有获得设备令牌,请尝试输入以下代码,以便为您的设备注册推送通知。

        它也适用于 ios8 或更高版本。

        #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000
        
            if ([UIApplication respondsToSelector:@selector(registerUserNotificationSettings:)]) {
                UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge|UIUserNotificationTypeAlert|UIUserNotificationTypeSound
                                                                                         categories:nil];
                [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
                [[UIApplication sharedApplication] registerForRemoteNotifications];
            } else {
                [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
                 UIRemoteNotificationTypeBadge |
                 UIRemoteNotificationTypeAlert |
                 UIRemoteNotificationTypeSound];
        
            }
        #else
            [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
             UIRemoteNotificationTypeBadge |
             UIRemoteNotificationTypeAlert |
             UIRemoteNotificationTypeSound];
        
        #endif
        

        【讨论】:

          【解决方案9】:

          在 Swift 3 中获取设备令牌

          func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
          
              let deviceTokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})
          
              print("Device token: \(deviceTokenString)")
          
          }
          

          【讨论】:

            【解决方案10】:

            在您的 AppDelegate 中,在 didRegisterForRemoteNotificationsWithDeviceToken 方法中:

            为 Swift 更新:

            func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
                print("\(deviceToken.reduce("") { $0 + String(format: "%02.2hhx", arguments: [$1]) })")
            }
            

            【讨论】:

              【解决方案11】:

              斯威夫特 4 这对我有用:

              步骤 1 进入 TARGETS 点击添加功能并选择 Push Notifications

              第二步在 AppDelegate.swift 中添加如下代码:

              func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
                   
                      UNUserNotificationCenter.current().requestAuthorization(options: [.alert,.sound]) { (didAllow, error) in
                          
                      }
                      UIApplication.shared.registerForRemoteNotifications()
                      
                      return true
                  }
                  
                  //Get device token
                  func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data)
                  {
                      let tokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})
                      
                      print("The token: \(tokenString)")
                  }
              

              【讨论】:

                【解决方案12】:

                对于 Objective-C

                iOS 13 推送令牌有一些变化

                - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
                NSString *token = @"";
                        if (@available(iOS 13, *)) {
                        NSUInteger length = deviceToken.length;
                        if (length == 0) {
                            token = @"";
                        }
                        const unsigned char *buffer = deviceToken.bytes;
                        NSMutableString *actualToken  = [NSMutableString stringWithCapacity:(length * 2)];
                        for (int i = 0; i < length; ++i) {
                            [actualToken appendFormat:@"%02x", buffer[i]];
                        }
                        token = [actualToken copy];
                        } else {
                            token = [[deviceToken description] stringByTrimmingCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:@"<>"]];
                                token = [token stringByReplacingOccurrencesOfString:@" " withString:@""];
                        }
                        NSLog(@"My token is: %@", token);
                }
                

                【讨论】:

                  【解决方案13】:

                  在构建设置集代码签名配置文件中,如果您有 APN 启用证书,那么您肯定会获得令牌 ID。并删除

                  配置文件:自动

                  并设置为

                  Provision Profile :您的配置文件证书。

                  【讨论】:

                    【解决方案14】:
                    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
                    
                        let tokenParts = deviceToken.map { data -> String in
                            return String(format: "%02.2hhx", data)
                            }
                        let token = tokenParts.joined()
                    
                        print("Token\(token)")
                    }
                    

                    【讨论】:

                      【解决方案15】:

                      为了获取设备令牌,请使用以下代码,但您只能使用物理设备获取设备令牌。如果您必须发送设备令牌,那么在使用模拟器时您可以设置以下条件。

                        if(!(TARGET_IPHONE_SIMULATOR))
                          {
                              [infoDict setValue:[[NSUserDefaults standardUserDefaults] valueForKey:@"DeviceToken"] forKey:@"device_id"];
                          }
                          else
                          {
                              [infoDict setValue:@"e79c2b66222a956ce04625b22e3cad3a63e91f34b1a21213a458fadb2b459385" forKey:@"device_id"];
                          }
                      
                      
                      
                      - (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
                      {
                          NSLog(@"My token is: %@", deviceToken);
                          NSString * deviceTokenString = [[[[deviceToken description] stringByReplacingOccurrencesOfString: @"<" withString: @""] stringByReplacingOccurrencesOfString: @">" withString: @""]   stringByReplacingOccurrencesOfString: @" " withString: @""];
                          NSLog(@"the generated device token string is : %@",deviceTokenString);
                          [[NSUserDefaults standardUserDefaults] setObject:deviceTokenString forKey:@"DeviceToken"];
                      }
                      

                      【讨论】:

                        猜你喜欢
                        • 2016-05-08
                        • 2010-11-23
                        • 1970-01-01
                        • 1970-01-01
                        • 2011-12-30
                        • 1970-01-01
                        • 1970-01-01
                        • 1970-01-01
                        相关资源
                        最近更新 更多