获取用于推送通知的设备令牌


84

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

- (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。

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


您遵循所有步骤了吗?如果您在认证和提供以及代码方面没有任何问题,那么您一定在犯一些小错误。像.tell我一样,您是否在实际设备上运行该应用程序并将其附加到系统上?您是否还注意到是否在控制台日志中获取设备令牌?您是否在iPhone中启用了推送通知
莎拉2012年

我无法在控制台日志上获取设备令牌。
jagzzz 2012年

我在真实设备上运行该应用程序,没有任何错误。
jagzzz 2012年

您是否按照iPhone上的链接所示启用了APNS?
莎拉

是的,我启用了APNS ..但是设备令牌无法在cosole上获取
jagzzz 2012年

Answers:


162

注意:以下解决方案不再适用于iOS 13+设备-它会返回垃圾数据

请改用以下代码:

+ (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)")
}

4
然后,请检查您的配置文件,该文件应该是您创建用于推送通知的ssl证书的应用ID。
Wasif Saood 2012年

1
您需要将代码添加到AppDelegate文件@jagzzz
codercat 2015年

2
对于那些对用Swift
Benjamin

3
小心,使用“描述”属性不再起作用:stackoverflow.com/questions/39495391/…–
hariseldon78

1
@codester我已经使用Xcode 10.3上传了我的构建,它是实时的。按照您的声明,Objective C方法将继续破坏XCode 11,但是我在数据库中看到的是它显示的是数据长度,而不是正确的apns令牌字符串。所以我只想知道,这取决于Xcode版本还是iOS版本(即13. *)?
pradip sutariya

13

要获得令牌设备,您可以按照以下步骤操作

1)为开发人员认证和分发认证启用APNS(苹果推送通知服务),然后重新下载这两个文件。

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

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

4)最后,您需要在AppDelegate文件中添加以下代码以获取令牌设备(注意:在真实设备中运行应用)。

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

11

使用description尽可能多的答案表明这是错误的方法-即使您可以使用它,它也会在iOS 13+中失效。

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

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()

7

iOS 13以上版本的Objective C,由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);

2
这从来不是正确的解决方案。切勿以任何东西为基础description
rmaddy19

5

Wasif的答案的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在二进制数据上使用(请参见其他答案)
cdstamper

4

如果仍然没有获取设备令牌,请尝试放置以下代码,以便为推送通知注册设备。

它也可以在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

3

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

我建议使用以下代码片段来解决问题:

+ (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及更低版本。


1
仅供参考-任何使用过的答案description都是错误的。这只是将令牌转换为字符串的一种可能的解决方案。一个更简单的解决方案是将转换NSDataNSString使用标准base64编码。
rmaddy19年

1

在Swift 3中获取设备令牌

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {

    let deviceTokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})

    print("Device token: \(deviceTokenString)")

}

1

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

为Swift更新:

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

0

Swift 4 这对我有用:

进入TARGETS的步骤1单击添加功能,然后选择“推送通知”

在AppDelegate.swift的步骤2中,添加以下代码:

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)")
    }

-1

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

供应配置文件:自动

并设置为

供应配置文件:您的供应配置文件证书。


-1
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)")
}

-4

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

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