2009-10-19 18 views
33

Tôi nhận được mã thông báo thiết bị iPhone ở dạng đối tượng NSData. Khi tôi kiểm tra chức năng tập lệnh thông báo của mình, tôi chỉ sao chép đối tượng đó từ nhật ký và các thông báo đã ổn. Tuy nhiên khi tôi cố gắng hiện nay để tự động làm điều đó, tôi đang gửi token thiết bị như ASCII chuỗi mã hóa dưới dạng biếnMã thông báo thiết bị iPhone - NSData hoặc NSString

self.deviceToken = [[NSString alloc] initWithData:webDeviceToken encoding:NSASCIIStringEncoding]; 

Chuỗi rằng tôi nhận được có một số nhân vật sôi nổi và trông tương tự như sau "å-0¾fZÿ÷ʺÎUQüRáqEªfÔk«"

Khi kịch bản lệnh phía máy chủ gửi thông báo đến mã thông báo đó, tôi không nhận được bất kỳ thông báo nào.

Tôi có cần giải mã một cái gì đó và cách thực hiện không?

Regardz

+0

Tôi tìm thấy giải pháp khác ở đây, có vẻ minh chứng hơn trong tương lai, sau đó là phương pháp "mô tả". http://stackoverflow.com/questions/1959600/how-to-use-objective-c-to-send-device-token-for-push-notifications-and-other-use –

+0

Điều kỳ lạ này, tôi nghĩ rằng NSData này * không nên là đối tượng đặc biệt, vì vậy tôi đã thử sử dụng NSUTF8StringEncoding và nhận kết quả khác. Tôi không thể chuyển đổi NSData thành NSString bằng phương thức ** description **! Một số tài liệu táo liên quan? – Itachi

Trả lời

107

Ok, tôi đã tìm được giải pháp. Nếu ai có cùng một vấn đề, quên mã hóa ASCII, chỉ cần thực hiện chuỗi với các dòng sau:

NSString *deviceToken = [[webDeviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]]; 
deviceToken = [deviceToken stringByReplacingOccurrencesOfString:@" " withString:@""]; 
+7

Xin vui lòng ngừng upvoting câu trả lời này, điều này sử dụng mã thông báo.description - đó chỉ là, một mô tả. Nó có nghĩa là để được đọc bởi một con người cho mục đích gỡ lỗi hoặc hiển thị. "<" and ">" không phải là một phần của mã thông báo, chúng chỉ dành cho định dạng hiển thị. Apple có thể thay đổi nó thành "[" hoặc "-" hoặc bất kỳ điều gì trong tương lai nếu họ muốn. Sử dụng một trong các câu trả lời để chuyển đổi dữ liệu thành chuỗi hex thay thế. –

2

Tôi không nghĩ rằng đó là một giải pháp tốt, vì bạn phải tái tạo lại chuỗi trước khi gửi thông báo đến Máy chủ Apple. Sử dụng mã hóa Base64 để truyền chuỗi hoặc tương tự.

+0

Chuỗi đã gửi hoạt động từ phía máy chủ mà không có bất kỳ sửa đổi hoặc sửa đổi nào – Mladen

+0

Nhưng theo tôi thấy, bạn đang xóa và cắt bớt các ký tự ... Bạn đã thử gửi thông báo bằng cách sử dụng mã thông báo đó và nó đã hoạt động chưa? Làm thế nào mà? –

+0

Tôi đã thử và đã hoạt động. – Mladen

5

Tôi thấy giải pháp này tốt hơn khi iOS có thể thay đổi cách sử dụng mô tả trong các phiên bản sau, vì vậy việc sử dụng thuộc tính mô tả trên dữ liệu có thể không đáng tin cậy trong tương lai. Chúng tôi có thể trực tiếp sử dụng điều này bằng cách tạo mã thông báo hex từ byte mã thông báo dữ liệu.

- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken { 
const unsigned *tokenBytes = [deviceToken bytes]; 
NSString *hexToken = [NSString stringWithFormat:@"%08x%08x%08x%08x%08x%08x%08x%08x", 
        ntohl(tokenBytes[0]), ntohl(tokenBytes[1]), ntohl(tokenBytes[2]), 
        ntohl(tokenBytes[3]), ntohl(tokenBytes[4]), ntohl(tokenBytes[5]), 
        ntohl(tokenBytes[6]), ntohl(tokenBytes[7])]; 
[[MyModel sharedModel] setApnsToken:hexToken]; 

}

Chúng tôi cũng có thể lưu trữ các thẻ điện thoại ở NSUserdefaults của chúng tôi và sử dụng nó sau này để gửi nó đi đến máy chủ của chúng tôi.

0

Một cách khác để chuyển đổi thiết bị Token vào hexa thập phân chuỗi

NSUInteger capacity = [deviceToken length] * 2; 
NSMutableString *stringBuffer = [NSMutableString stringWithCapacity:capacity]; 
const unsigned char *dataBuffer = [deviceToken bytes]; 
NSInteger i; 
for (i=0; i<[deviceToken length]; ++i) { 
    [stringBuffer appendFormat:@"%02X", (NSUInteger)dataBuffer[i]]; 
} 
NSLog(@"token string buffer is %@",stringBuffer); 
43

Nếu bất cứ ai đang tìm kiếm một cách để làm điều này trong Swift:

func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) { 
    let tokenChars = UnsafePointer<CChar>(deviceToken.bytes) 
    var tokenString = "" 

    for i in 0..<deviceToken.length { 
     tokenString += String(format: "%02.2hhx", arguments: [tokenChars[i]]) 
    } 

    print("tokenString: \(tokenString)") 
} 

Edit: Đối với Swift 3

Swift 3 giới thiệu loại Data, với ngữ nghĩa giá trị.Để chuyển đổi các deviceToken vào một String, bạn có thể làm như sau:

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

    var token: String = "" 
    for i in 0..<deviceToken.count { 
     token += String(format: "%02.2hhx", deviceToken[i] as CVarArg) 
    } 

    print(token) 
} 
+0

Thx! Chính xác những gì tôi cần! – kimimaro

+1

Điều ngạc nhiên là không có cách nào dễ dàng để nhanh chóng nhận được dữ liệu chuỗi được giải mã thích hợp từ đối tượng mã thông báo thiết bị NSData. Nhưng đây là ví dụ fro @sascha là điều đầu tiên tôi gặp phải thực sự hiệu quả! Cảm ơn bạn. – Shiprack

+1

Bây giờ di chuyển nó sang phần mở rộng NSData và gọi nó là 'hexadecimalStringDescription() ' – Eimantas

0

Đối Swift 3:

var tokenString: String = "" 
    for i in 0..<deviceToken.count { 
     tokenString += String(format: "%02.2hhx", deviceToken[i] as CVarArg) 
    } 

    print(tokenString) 

khác Phương pháp

Tạo mở rộng dữ liệu để nhận hexstring

extension Data { 
    var hexString: String { 
     return map { String(format: "%02.2hhx", arguments: [$0]) }.joined() 
    } 
} 

Và hãy gọi tiện ích mở rộng này trong

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { 
    let tokenString = deviceToken.hexString() 
    print("token: \(tokenString)") 
} 
+0

Điều này làm việc cho Swift 2.0. Cảm ơn. –

+0

Đừng dựa vào .description, định dạng bạn nhận được từ đó không có giấy tờ và có thể thay đổi về mặt kỹ thuật. deviceToken.description chỉ nên được sử dụng cho mục đích gỡ lỗi. Sử dụng một trong các câu trả lời để chuyển đổi các byte thành chuỗi hex thay thế. –

+2

đã đồng ý. Không sử dụng điều này. Khi sử dụng PKPushCredentials, mô tả hiện trả về "32 byte" – Tony