web-dev-qa-db-ja.com

iPhoneデバイストークン-NSDataまたはNSString

NSDataオブジェクトの形式でiPhoneデバイストークンを受け取っています。通知スクリプト関数をテストしたところ、ログからそのオブジェクトをコピーしただけで、通知は正常に行われました。ただし、自動で実行しようとすると、デバイストークンがASCIIエンコードされた変数の形式の文字列として送信されます。

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

私が取得している文字列には、いくつかのファンキーな文字が含まれており、これに似ています"å-0¾fZÿ÷ʺÎUQüRáqEªfÔk«"

サーバー側のスクリプトがそのトークンに通知を送信すると、何も受信されません。

何かをどのようにデコードする必要がありますか?

よろしく

33
Mladen

はい、解決策を見つけました。誰かが同じ問題を抱えている場合は、ASCIIエンコーディングについては忘れてください。次の行で文字列を作成してください。

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

誰かがこれを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)")
}

編集:Swift 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)
}
44
Sascha

IOSは将来のバージョンで説明の使用法を変更できるため、この解決策を見つけました。データで説明プロパティを使用することは、将来的に信頼できなくなる可能性があります。データトークンバイトから16進トークンを作成することで、これを直接使用できます。

 - (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にデバイストークンを保存し、後でそれを使用してサーバーに送信することもできます。

5
megha

Appleサーバーに通知を送信する前に文字列を再構築する必要があるため、これは適切な解決策ではないと思います。文字列または同様の何かを送信するには、Base64エンコーディングを使用してください。

2
M. Broncano

デバイストークンをヘキサ10進文字列に変換する別の方法

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);
0
aparna

Swift 3:の場合

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

    print(tokenString)

その他の方法

16進文字列を取得するためのデータ拡張を作成する

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
Adarsh G J