Nhận mã thông báo thiết bị cho thông báo đẩy


84

Tôi đang làm việc trên thông báo đẩy. Tôi đã viết mã sau để tìm nạp mã thông báo thiết bị.

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

Tôi có thể chạy ứng dụng trên thiết bị thành công nhưng không thể lấy id thiết bị trên bảng điều khiển.

Tôi không gặp vấn đề gì với hồ sơ chứng nhận và cấp phép.


Bạn đã làm theo tất cả các bước ? Nếu bạn không gặp bất kỳ vấn đề nào với chứng nhận và cung cấp cũng như mã thì chắc chắn bạn đang mắc một số lỗi nhỏ. Giống như..nói cho tôi biết, bạn có đang chạy ứng dụng trên thiết bị thực gắn giống với hệ thống của bạn không? Ngoài ra, bạn có để ý xem bạn có nhận được mã thông báo thiết bị trong nhật ký bảng điều khiển hay không? Bạn đã bật Thông báo đẩy trong iPhone chưa?
Sarah

Tôi không thể nhận mã thông báo thiết bị trên nhật ký bảng điều khiển.
jagzzz

Tôi đang chạy ứng dụng trên thiết bị thực mà không gặp bất kỳ lỗi nào.
jagzzz

Bạn đã bật APNS như được hiển thị trong liên kết trên iPhone chưa?
Sarah

yes i kích hoạt APNS..but thiết bị thẻ không phải là có thể lấy trên cosole
jagzzz

Câu trả lời:


162

LƯU Ý: Giải pháp dưới đây không còn hoạt động trên thiết bị iOS 13+ - nó sẽ trả về dữ liệu rác .

Vui lòng sử dụng mã sau để thay thế:

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

Giải pháp hoạt động trước iOS 13:

Objective-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

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
Sau đó, vui lòng kiểm tra hồ sơ cấp phép của bạn, hồ sơ đó phải là ID ứng dụng mà bạn đã tạo chứng chỉ ssl của mình cho thông báo đẩy.
Wasif Saood

1
bạn cần thêm mã vào tệp AppDelegate @jagzzz
codercat

2
Đối với những người quan tâm đến một mã ví dụ writtent trong Swift: gist.github.com/sawapi/a7cee65e4ad95578044d
Benjamin

3
Cẩn thận, sử dụng "mô tả" bất động sản không còn hoạt động: stackoverflow.com/questions/39495391/...
hariseldon78

1
@codester Tôi đã tải lên bản dựng của mình bằng Xcode 10.3 và nó đang hoạt động. Theo tuyên bố của bạn, phương thức Objective C sẽ bị hỏng XCode 11 trở đi nhưng những gì tôi có thể thấy trong cơ sở dữ liệu của chúng tôi, nó đang hiển thị độ dài dữ liệu thay vì một chuỗi mã thông báo apns đúng. Vì vậy, tôi chỉ muốn biết rằng, Nó phụ thuộc vào phiên bản Xcode hay phiên bản iOS (tức là 13. *)?
pradip sutariya

13

Để có được Thiết bị Mã thông báo, bạn có thể thực hiện theo một số bước :

1) Bật APNS (Dịch vụ thông báo đẩy của Apple) cho cả Chứng nhận nhà phát triển và Chứng nhận phân phối, sau đó tải xuống hai tệp đó.

2) Tải xuống lại cả tệp Cấp phép dành cho nhà phát triển và Phân phối cấp phép.

3) Trong giao diện Xcode: thiết lập cung cấp cho DỰ ÁN và TARGETS với hai tệp cung cấp có tải xuống.

4) Cuối cùng, bạn cần thêm đoạn mã bên dưới vào tệp AppDelegate để lấy Thiết bị Mã thông báo (lưu ý: chạy ứng dụng trên thiết bị thực).

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

Sử dụng descriptioncàng nhiều câu trả lời trong số những câu trả lời này gợi ý là cách tiếp cận sai - ngay cả khi bạn làm cho nó hoạt động, nó sẽ bị hỏng trong iOS 13+.

Thay vào đó, bạn nên đảm bảo bạn sử dụng dữ liệu nhị phân thực tế, không chỉ đơn giản là mô tả về nó. Andrey Gagan đã giải quyết khá tốt giải pháp Objective C, nhưng may mắn thay, nó đơn giản hơn nhiều trong thời gian nhanh chóng:

Swift 4.2 hoạt động trên 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

Objective C dành cho iOS 13+ , với câu trả lời của Wasif Saood

Sao chép và dán mã bên dưới vào AppDelegate.m để in mã thông báo APN của thiết bị.

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

Mã sau được sử dụng để truy xuất mã thông báo thiết bị.

    // 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
Đây chưa bao giờ là giải pháp chính xác. Không bao giờ dựa trên bất cứ điều gì description.
rmaddy

5

Và phiên bản Swift của câu trả lời của Wasif:

Swift 2.x

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

Cập nhật cho Swift 3

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

Không bao giờ sử dụng descriptiontrên dữ liệu nhị phân (xem bất kỳ câu trả lời khác)
cdstamper

4

Nếu bạn vẫn không nhận được mã thông báo thiết bị, hãy thử nhập mã sau để đăng ký thiết bị của bạn cho thông báo đẩy.

Nó cũng sẽ hoạt động trên ios8 trở lên.

#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

Bắt đầu từ iOS 13 Apple đã thay đổi [deviceToken description]đầu ra. Bây giờ nó giống như thế này {length=32,bytes=0x0b8823aec3460e1724e795cba45d22e8...af8c09f971d0dabc}là không chính xác cho mã thông báo thiết bị.

Tôi khuyên bạn nên sử dụng đoạn mã này để giải quyết vấn đề:

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

Nó sẽ hoạt động cho iOS13 trở xuống.


1
FYI - bất kỳ câu trả lời nào từng được sử dụng descriptionluôn sai. Và đây chỉ là một giải pháp khả thi để chuyển đổi mã thông báo thành một chuỗi. Một giải pháp đơn giản hơn nhiều là chuyển đổi NSDatasang NSStringmã hóa base64 tiêu chuẩn.
rmaddy

1

Nhận mã thông báo thiết bị trong Swift 3

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

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

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

}

1

Trong AppDelegate của bạn, trong didRegisterForRemoteNotificationsWithDeviceTokenphương thức:

Cập nhật cho Swift:

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

0

Swift 4 Điều này phù hợp với tôi:

Bước 1 vào MỤC TIÊU Nhấp vào thêm khả năng và chọn Thông báo đẩy

Bước 2 trong AppDelegate.swift, hãy thêm mã sau:

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

Trong cài đặt xây dựng, thiết lập hồ sơ cung cấp ký mã nếu bạn có chứng chỉ Kích hoạt APN thì bạn chắc chắn sẽ nhận được mã thông báo id. và loại bỏ

Hồ sơ cung cấp: Tự động

và đặt thành

Hồ sơ cung cấp: Giấy chứng nhận hồ sơ cung cấp của bạn.


-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

Để nhận mã thông báo thiết bị, hãy sử dụng mã sau nhưng bạn chỉ có thể nhận mã thông báo thiết bị bằng thiết bị vật lý. Nếu bạn bắt buộc phải gửi mã thông báo thiết bị thì trong khi sử dụng trình mô phỏng, bạn có thể đặt điều kiện bên dưới.

  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"];
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.