简体   繁体   English

获取推送通知的设备令牌

[英]Get device token for push notification

I am working on push notifications.我正在处理推送通知。 I wrote the following code for fetching a device token.我编写了以下代码来获取设备令牌。

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

I am able to run application on device successfully but not able to get the device id on console.我能够在设备上成功运行应用程序,但无法在控制台上获取设备 ID。

I have no issues with certification and provisioning profiles.我对认证和配置文件没有任何问题。

NOTE: The below solution no longer works on iOS 13+ devices - it will return garbage data .注意:以下解决方案不再适用于 iOS 13+ 设备 -它将返回垃圾数据

Please use following code instead:请改用以下代码:

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

Solution that worked prior to iOS 13:在 iOS 13 之前运行的解决方案:

Objective-C目标-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);
} 

Swift 3.0斯威夫特 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)")
}

To get Token Device you can do by some steps :要获得令牌设备,您可以通过以下步骤进行

1) Enable APNS (Apple Push Notification Service) for both Developer Certification and Distribute Certification, then redownload those two file. 1) 为开发者认证和分发认证启用 APNS(Apple 推送通知服务),然后重新下载这两个文件。

2) Redownload both Developer Provisioning and Distribute Provisioning file. 2) 重新下载 Developer Provisioning 和 Distribute Provisioning 文件。

3) In Xcode interface: setting provisioning for PROJECT and TARGETS with two file provisioning have download. 3)在Xcode界面:设置PROJECT和TARGETS的provisioning,两个文件provisioning已经下载。

4) Finally, you need to add the code below in AppDelegate file to get Token Device (note: run app in real device). 4)最后,需要在AppDelegate文件中添加如下代码来获取Token Device(注意:在真机上运行app)。

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

Using description as many of these answers suggest is the wrong approach - even if you get it to work, it will break in iOS 13+.使用其中许多答案所暗示的description错误的方法- 即使你让它工作,它也会在 iOS 13+ 中崩溃。

Instead you should ensure you use the actual binary data, not simply a description of it.相反,您应该确保使用实际的二进制数据,而不仅仅是对它的描述。 Andrey Gagan addressed the Objective C solution quite well, but fortunately it's much simpler in swift: Andrey Gagan 很好地解决了 Objective C 解决方案,但幸运的是它在 swift 中要简单得多:

Swift 4.2 works in iOS 13+ 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()

Objective C for iOS 13+ , courtesy of Wasif Saood's answer iOS 13+ 的 Objective C ,由 Wasif Saood 的回答提供

Copy and paste below code into AppDelegate.m to print the device APN token.将以下代码复制并粘贴到 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);
}

And the Swift version of the Wasif's answer:以及 Wasif 答案的 Swift 版本:

Swift 2.x斯威夫特 2.x

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

Update for Swift 3 Swift 3 更新

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

Starting from iOS 13 Apple has changed [deviceToken description] output.从 iOS 13 开始,Apple 更改了[deviceToken description]输出。 Now it is like this {length=32,bytes=0x0b8823aec3460e1724e795cba45d22e8...af8c09f971d0dabc} which is incorrect for device token.现在就像这样{length=32,bytes=0x0b8823aec3460e1724e795cba45d22e8...af8c09f971d0dabc}这对于设备令牌是不正确的。

I suggest to use this code snippet to resolve a problem:我建议使用此代码片段来解决问题:

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

It will work for iOS13 and lower.它适用于 iOS13 及更低版本。

Following code is use for the retrive the device token.以下代码用于检索设备令牌。

    // 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);

If you are still not getting device token, try putting following code so to register your device for push notification.如果您仍然没有获得设备令牌,请尝试输入以下代码以便注册您的设备以接收推送通知。

It will also work on ios8 or more.它也适用于 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

In your AppDelegate, in the didRegisterForRemoteNotificationsWithDeviceToken method:在您的 AppDelegate 中,在didRegisterForRemoteNotificationsWithDeviceToken方法中:

Updated for Swift:为 Swift 更新:

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

Get device token in Swift 3在 Swift 3 中获取设备令牌

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

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

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

}

Get device token in swift 3 在swift 3中获取设备令牌

 func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        let token = String(format: "%@", deviceToken as CVarArg).trimmingCharacters(in: CharacterSet(charactersIn: "<>")).replacingOccurrences(of: " ", with: "")
        print(token)
    }

Swift 4 This works for me: Swift 4这对我有用:

Step 1 into TARGETS Click on add capability and select Push Notifications第 1 步进入TARGETS单击添加功能并选择推送通知

Step 2 in AppDelegate.swift add the following code:在 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)")
    }

For Objective-C对于 Objective-C

There are some changes for the iOS 13 push token 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);
}

In a build setting set code signing Provision Profile if you have APN Enable certificate then you will definitely get the token id.在构建设置中设置代码签名配置文件,如果您有 APN Enable 证书,那么您肯定会获得令牌 ID。 and remove并删除

Provision Profile : Automatic配置文件:自动

and set to并设置为

Provision Profile : Your provision profile certificate.配置文件:您的配置文件证书。

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

In order to get the device token use following code but you can get the device token only using physical device.为了获取设备令牌,请使用以下代码,但您只能使用物理设备获取设备令牌。 If you have mandatory to send the device token then while using simulator you can put the below condition.如果您必须发送设备令牌,那么在使用模拟器时,您可以设置以下条件。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM