wake-up-neo.net

UTF-8-kodierte NSData in NSString konvertieren

Ich habe UTF-8 NSData vom Windows-Server codiert und möchte es für iPhone in NSString konvertieren. Da Daten Zeichen (wie ein Gradsymbol) enthalten, die auf beiden Plattformen unterschiedliche Werte haben, ist wie konvertiere ich Daten in Zeichenfolge?

553
Ashwini

Wenn die Daten nicht nullterminiert sind, sollten Sie -initWithData:encoding: verwenden.

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

Wenn die Daten nullterminiert sind, sollten Sie stattdessen -stringWithUTF8String: verwenden, um den zusätzlichen \0 am Ende zu vermeiden.

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

(Beachten Sie, dass bei ungenauer UTF-8-Kodierung nil angezeigt wird.)


Schnelle Variante:

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

Wenn die Daten nullterminiert sind, können Sie den sicheren Weg gehen, der das Nullzeichen entfernt, oder den unsicheren Weg, der der Objective-C-Version ähnlich ist.

// 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:))
1132
kennytm

Sie können diese Methode aufrufen 

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

Ich gebe demütig eine Kategorie ein, um das weniger lästig zu machen:

@interface NSData (EasyUTF8)

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

@end

und

@implementation NSData (EasyUTF8)

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

@end

(Beachten Sie, dass Sie, wenn Sie ARC nicht verwenden, eine autorelease dort benötigen.)

Jetzt anstelle der entsetzlich wortreich:

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

Du kannst tun:

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

Die Swift-Version von String zu Data und zurück zu String:

Xcode 10.1 • Swift 4.2.1

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

extension StringProtocol {
    var data: Data {
        return Data(utf8)
    }
}

extension String {
    var base64Decoded: Data? {
        return Data(base64Encoded: self)
    }
}

Spielplatz

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 ?? "nil")                    // "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"
18
Leo Dabus

Manchmal funktionieren die Methoden in den anderen Antworten nicht. In meinem Fall generiere ich eine Signatur mit meinem privaten RSA-Schlüssel und das Ergebnis ist NSData. Ich habe festgestellt, dass dies zu funktionieren scheint:

Ziel c

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

Swift

let signatureString = signature.base64EncodedStringWithOptions(nil)
15
mikeho

Um es zusammenzufassen: Hier ist eine vollständige Antwort, die für mich funktioniert hat.

Mein Problem war das, als ich es benutzte 

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

Die Saite, die ich bekam, war unvorhersehbar: Ungefähr 70% enthielten den erwarteten Wert, aber zu oft kam es zu Null oder noch schlimmer: am Ende der Saite war kein Speicherplatz.

Nach einigem Graben wechselte ich zu 

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

Und bekam jedes Mal das erwartete Ergebnis.

1
Gal

Mit Swift 4.2 können Sie Strings init(data:encoding:) initializer verwenden, um eine Data-Instanz mit UTF-8 in eine String-Instanz zu konvertieren. init(data:encoding:) hat die folgende Deklaration:

init?(data: Data, encoding: String.Encoding)

Gibt eine String zurück, die durch Konvertieren der angegebenen Daten in Unicode-Zeichen unter Verwendung einer angegebenen Kodierung initialisiert wurde.

Der folgende Code für den Spielplatz zeigt, wie er verwendet wird:

import Foundation

let json = """
{
"firstName" : "John",
"lastName" : "Doe"
}
"""

let data = json.data(using: String.Encoding.utf8)!

let optionalString = String(data: data, encoding: String.Encoding.utf8)
print(String(describing: optionalString))

/*
 prints:
 Optional("{\n\"firstName\" : \"John\",\n\"lastName\" : \"Doe\"\n}")
*/
0
Imanou Petit