2009-10-19 42 views
33

我正在以NSData對象的形式接收iPhone設備令牌。 當我測試了我的通知腳本函數時,我只從日誌中複製了該對象,並且通知正常。然而,當我現在嘗試自動做到這一點,我向設備發送令牌作爲ASCII編碼字符串中的變量Iphone設備令牌-NSData或NSString

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

的字符串,我得到了一些時髦的人物和類似於這樣"å-0¾fZÿ÷ʺÎUQüRáqEªfÔk«"

形式

當服務器端腳本將通知發送給該令牌時,我沒有收到任何內容。

我是否需要解碼某些東西以及如何解碼?

Regardz

+0

我發現了另一個解決方案在這裏,看上去更加面向未來的,則「說明」的方法。 http://stackoverflow.com/questions/1959600/how-to-use-objective-c-to-send-device-token-for-push-notifications-and-other-use – 2013-03-19 09:07:56

+0

這很奇怪,我認爲這NSData *不應該是特殊的對象,所以我嘗試使用NSUTF8StringEncoding並獲得不同的結果。使用** description **方法將NSData轉換爲NSString是不可想象的!一些蘋果文檔有關? – Itachi 2015-07-21 09:17:54

回答

107

好的,我找到了解決方案。如果任何人有同樣的問題,忘掉ASCII編碼,只要有以下行字符串:

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

請停止upvoting這個答案,這使用令牌.description - 就是這樣一個描述。它是爲了調試或顯示而被人讀取的。 「<" and ">」不是令牌的一部分,它們僅用於顯示格式。如果他們想要,蘋果公司可以將其改爲「[」或「 - 」或其他什麼。使用其中一個將數據轉換爲十六進制字符串的答案。 – 2016-05-25 03:37:09

2

我不認爲這是一個很好的解決方案,因爲你發送通知之前重建串Apple服務器。使用Base64編碼傳輸字符串或類似的東西。

+0

發送字符串從服務器端工作,沒有任何重建或修改 – Mladen 2009-10-19 09:31:36

+0

但據我所知,您正在刪除和修剪字符...您是否嘗試使用該標記發送通知,它的工作?怎麼來的? – 2009-10-19 09:51:14

+0

我已經嘗試過,它工作。 – Mladen 2009-10-19 09:56:25

5

我發現這個解決方案更好,因爲iOS可以在將來的版本中更改描述的用法,所以在將來使用數據的描述屬性可能不可靠。 我們可以通過從數據標記字節中創建十六進制令牌來直接使用它。

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

}

我們也可以存儲在我們的NSUserDefaults的設備令牌和使用它以後將其發送到我們的服務器。

0

設備令牌轉換爲六十進制字符串

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

如果有人正在尋找一種方式,斯威夫特做到這一點的另一種方式:

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

編輯:對於斯威夫特3

Swift 3引入了帶有值語義的Data類型。要將deviceToken轉換爲字符串,你可以做如下:

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!正是我需要的! – kimimaro 2015-01-25 04:01:09

+1

令人驚訝的是,在swift中沒有簡單的方法從NSData設備令牌對象中獲取正確解碼的字符串數據。但是這是一個例子,@sascha是我遇到的第一個實際工作的東西!謝謝。 – Shiprack 2015-02-21 14:35:12

+1

現在將其移至NSData擴展名並將其稱爲'hexadecimalStringDescription()' – Eimantas 2015-11-13 09:09:19

0

對於斯威夫特3:

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

    print(tokenString) 

其他方法

創建數據擴展獲得比特產

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

並稱之爲擴展在

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

這適用於Swift 2.0。謝謝。 – 2015-12-11 07:38:25

+0

不要依賴.description,你從中得到的格式沒有記錄,並且在技術上可能會改變。 deviceToken.description只能用於調試目的。使用其中一個將字節轉換爲十六進制字符串的答案。 – 2016-05-25 03:33:12

+2

同意。不要使用這個。當使用PKPushCredentials時,描述現在返回「32字節」 – Tony 2016-10-03 19:06:38