Convertir UTF-8 encoded NSData en NSString

J'ai UTF-8 encodé NSData de windows server 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?

548
demandé sur Bhavin Ramani 2010-03-18 09:17:49

6 réponses

si les données ne sont pas nulles, vous devez utiliser -initWithData:encoding:

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

si les données sont nulles, vous devriez plutôt utiliser -stringWithUTF8String: pour éviter le " 151960920 " supplémentaire à la fin.

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

(notez que si L'entrée N'est pas correctement encodée en UTF-8, vous obtiendrez nil .)


variante Swift:

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

Si les données sont null-terminated, vous pouvez passer par la voie sûre qui est de supprimer le caractère null, ou la manière dangereuse similaire à la version de L'Objectif-C ci-dessus.

// safe way, provided data is "151930920"-terminated
let newStr1 = String(data: data.subdata(in: 0 ..< data.count - 1), encoding: .utf8)
// unsafe way, provided data is "151930920"-terminated
let newStr2 = data.withUnsafeBytes(String.init(utf8String:))
1122
répondu kennytm 2017-12-25 09:32:42

vous pouvez appeler cette méthode

+(id)stringWithUTF8String:(const char *)bytes.
28
répondu Gouldsc 2012-09-12 05:42:00

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 ).)

maintenant au lieu de l'épouvantablement verbeux:

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

Vous pouvez le faire:

NSData *data = ...
[data asUTF8String];
19
répondu Claudiu 2014-02-20 15:19:09

la version Swift de la chaîne de caractères aux données et Retour à la chaîne de caractères:

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

Terrain de jeux

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"
16
répondu Leo Dabus 2018-05-15 10:43:00

Parfois, les méthodes dans les 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];

Swift

let signatureString = signature.base64EncodedStringWithOptions(nil)
14
répondu mikeho 2014-12-20 15:27:16

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

mon problème était que lorsque j'ai utilisé

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

la chaîne que j'ai reçue était imprévisible: environ 70% elle contenait la valeur attendue, mais trop souvent elle a résulté avec Null ou pire encore: garbaged à la fin de la chaîne.

après quelques fouilles, je suis passé à

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

et obtenu le résultat attendu chaque temps.

1
répondu Gal 2015-11-29 18:52:25