NSData
オブジェクトの形式でiPhoneデバイストークンを受け取っています。通知スクリプト関数をテストしたところ、ログからそのオブジェクトをコピーしただけで、通知は正常に行われました。ただし、自動で実行しようとすると、デバイストークンがASCIIエンコードされた変数の形式の文字列として送信されます。
self.deviceToken = [[NSString alloc] initWithData:webDeviceToken encoding:NSASCIIStringEncoding];
私が取得している文字列には、いくつかのファンキーな文字が含まれており、これに似ています"å-0¾fZÿ÷ʺÎUQüRáqEªfÔk«"
サーバー側のスクリプトがそのトークンに通知を送信すると、何も受信されません。
何かをどのようにデコードする必要がありますか?
よろしく
はい、解決策を見つけました。誰かが同じ問題を抱えている場合は、ASCIIエンコーディングについては忘れてください。次の行で文字列を作成してください。
NSString *deviceToken = [[webDeviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
deviceToken = [deviceToken stringByReplacingOccurrencesOfString:@" " withString:@""];
誰かがこれを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では、値のセマンティクスを持つ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)
}
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にデバイストークンを保存し、後でそれを使用してサーバーに送信することもできます。
Appleサーバーに通知を送信する前に文字列を再構築する必要があるため、これは適切な解決策ではないと思います。文字列または同様の何かを送信するには、Base64エンコーディングを使用してください。
デバイストークンをヘキサ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);
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)")
}