Question Convertir NSData codé UTF-8 en NSString


J'ai codé en UTF-8 NSData à partir du serveur Windows et je veux le convertir en NSString pour iphone. Puisque les données contiennent des caractères (comme un symbole de degré) qui ont des valeurs différentes sur les deux plates-formes, comment puis-je convertir des données en chaîne?


547
2018-03-18 06:17


origine


Réponses:


Si les données ne sont pas terminées par un caractère nul, vous devez utiliser -initWithData:encoding:

NSString* newStr = [[NSString alloc] initWithData:theData encoding:NSUTF8StringEncoding];

Si les données sont terminées par un caractère nul, vous devez plutôt utiliser -stringWithUTF8String: pour éviter le supplément \0 à la fin.

NSString* newStr = [NSString stringWithUTF8String:[theData bytes]];

(Notez que si l'entrée n'est pas correctement codée en UTF-8, vous obtiendrez nil.)


Swift variante:

let newStr = String(data: data, encoding: .utf8)
// note that `newStr` is a `String?`, not a `String`.

Si les données sont terminées par un caractère nul, vous pouvez utiliser la méthode sûre qui consiste à supprimer le caractère null, ou la méthode non sécurisée similaire à la version Objective-C ci-dessus.

// safe way, provided data is \0-terminated
let newStr1 = String(data: data.subdata(in: 0 ..< data.count - 1), encoding: .utf8)
// unsafe way, provided data is \0-terminated
let newStr2 = data.withUnsafeBytes(String.init(utf8String:))

1120
2018-03-18 06:20



Vous pourriez appeler cette méthode

+(id)stringWithUTF8String:(const char *)bytes.

28
2018-03-18 06:25



Je soumets humblement une catégorie pour rendre cela moins ennuyeux:

@interface NSData (EasyUTF8)

// Safely decode the bytes into a UTF8 string
- (NSString *)asUTF8String;

@end

et

@implementation NSData (EasyUTF8)

- (NSString *)asUTF8String {
    return [[NSString alloc] initWithData:self encoding:NSUTF8StringEncoding];    
}

@end

(Notez que si vous n'utilisez pas ARC, vous aurez besoin d'un autorelease Là.)

Maintenant, au lieu de l'effroyablement verbeux:

NSData *data = ...
[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

Tu peux faire:

NSData *data = ...
[data asUTF8String];

19
2017-10-01 23:04



La version Swift de String à Data et retour à String:

Xcode 9 • Swift 4

extension Data {
    var string: String {
        return String(data: self, encoding: .utf8) ?? ""
    }
}
extension String {
    var data: Data {
        return Data(utf8)
    }
    var base64Decoded: Data? {
        return Data(base64Encoded: self)
    }
}

Cour de récréation

let string = "Hello World"                                  // "Hello World"
let stringData = string.data                                // 11 bytes
let base64EncodedString = stringData.base64EncodedString()  // "SGVsbG8gV29ybGQ="
let stringFromData = stringData.string                      // "Hello World"

let base64String = "SGVsbG8gV29ybGQ="
if let data = base64String.base64Decoded {
    print(data)                                    //  11 bytes
    print(data.base64EncodedString())              // "SGVsbG8gV29ybGQ="
    print(data.string)                             // "Hello World"
}

let stringWithAccent = "Olá Mundo"                          // "Olá Mundo"
print(stringWithAccent.count)                               // "9"
let stringWithAccentData = stringWithAccent.data            // "10 bytes" note: an extra byte for the acute accent
let stringWithAccentFromData = stringWithAccentData.string  // "Olá Mundo\n"

15
2018-02-15 03:51



Parfois, les méthodes des autres réponses ne fonctionnent pas. Dans mon cas, je génère une signature avec ma clé privée RSA et le résultat est NSData. J'ai trouvé que cela semble fonctionner:

Objectif c

NSData *signature;
NSString *signatureString = [signature base64EncodedStringWithOptions:0];

Rapide

let signatureString = signature.base64EncodedStringWithOptions(nil)

14
2018-05-19 23:42



Pour résumer, voici une réponse complète, qui a fonctionné pour moi.

Mon problème était que quand j'ai utilisé

[NSString stringWithUTF8String:(char *)data.bytes];

La chaîne que j'ai eu était imprévisible: environ 70% contenait la valeur attendue, mais trop souvent Null ou pire encore: garbaged à la fin de la chaîne.

Après quelques recherches je suis passé à

[[NSString alloc] initWithBytes:(char *)data.bytes length:data.length encoding:NSUTF8StringEncoding];

Et obtenu le résultat attendu à chaque fois.


1
2017-11-29 18:52