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?
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.)
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:))
Sie können diese Methode aufrufen
+(id)stringWithUTF8String:(const char *)bytes.
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];
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"
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)
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.
Mit Swift 4.2 können Sie String
s 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}")
*/