Je reçois un jeton d'appareil iPhone sous la forme d'un objet NSData
. Lorsque j'ai testé la fonction de script de notification, je n'ai copié que cet objet à partir du journal et les notifications se sont bien déroulées. Cependant, quand j'essaie maintenant de le faire automatiquement, j'envoie le jeton de périphérique sous la forme d'une chaîne codée ASCII sous la forme d'une variable
self.deviceToken = [[NSString alloc] initWithData:webDeviceToken encoding:NSASCIIStringEncoding];
La chaîne que je reçois a quelques caractères géniaux et ressemble à ceci "å-0¾fZÿ÷ʺÎUQüRáqEªfÔk«"
Lorsque le script côté serveur envoie la notification à ce jeton, je ne reçois rien.
Dois-je décoder quelque chose et comment?
Regardz
Ok, j'ai trouvé une solution. Si quelqu'un a le même problème, oubliez le codage ASCII, créez simplement la chaîne avec les lignes suivantes:
NSString *deviceToken = [[webDeviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
deviceToken = [deviceToken stringByReplacingOccurrencesOfString:@" " withString:@""];
Si quelqu'un cherche un moyen de faire cela à 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 introduit le type Data
, avec une sémantique de valeur. Pour convertir la deviceToken
en chaîne, procédez comme suit:
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)
}
J'ai trouvé cette solution mieux, car iOS peut modifier l'utilisation de la description dans les versions futures, de sorte que l'utilisation de la propriété de description sur les données peut ne plus être fiable à l'avenir.
- (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];
}
Nous pouvons également stocker le jeton de périphérique dans nos NSUserdefaults et l'utiliser ultérieurement pour l'envoyer à notre serveur.
Je ne pense pas que ce soit une bonne solution, car vous devez reconstruire la chaîne avant d'envoyer les notifications aux serveurs Apple. Utilisez le codage Base64 pour transmettre les chaînes ou quelque chose de similaire.
Une autre façon de convertir un jeton de périphérique en chaîne hexa décimale
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);
Pour Swift 3:
var tokenString: String = ""
for i in 0..<deviceToken.count {
tokenString += String(format: "%02.2hhx", deviceToken[i] as CVarArg)
}
print(tokenString)
Autre méthode
Créer une extension de données pour obtenir hexstring
extension Data {
var hexString: String {
return map { String(format: "%02.2hhx", arguments: [$0]) }.joined()
}
}
Et appelez cette extension dans
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let tokenString = deviceToken.hexString()
print("token: \(tokenString)")
}