Convert UTF-8 encoded NSData to NSString
我有来自WindowsServer的UTF-8编码的
如果数据不是以空结尾,则应使用
1 | NSString* newStr = [[NSString alloc] initWithData:theData encoding:NSUTF8StringEncoding]; |
如果数据为空终止,则应改为使用
1 | NSString* newStr = [NSString stringWithUTF8String:[theData bytes]]; |
(请注意,如果输入的utf-8编码不正确,您将得到
1 2 | let newStr = String(data: data, encoding: .utf8) // note that `newStr` is a `String?`, not a `String`. |
如果数据是以空结尾的,您可以使用删除该空字符的安全方法,或者类似于上面的Objective-C版本的不安全方法。
1 2 3 4 | // 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:)) |
你可以调用这个方法
1 | +(id)stringWithUTF8String:(const char *)bytes. |
我谦虚地提交了一个类别,以减少这一烦人:
1 2 3 4 5 6 | @interface NSData (EasyUTF8) // Safely decode the bytes into a UTF8 string - (NSString *)asUTF8String; @end |
和
1 2 3 4 5 6 7 | @implementation NSData (EasyUTF8) - (NSString *)asUTF8String { return [[NSString alloc] initWithData:self encoding:NSUTF8StringEncoding]; } @end |
(请注意,如果您不使用ARC,您将需要一个
现在不再是令人震惊的冗长:
1 2 | NSData *data = ... [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; |
你可以做到:
1 2 | NSData *data = ... [data asUTF8String]; |
从字符串到数据再到字符串的swift版本:
XCODE 10.1?SWIFT 4.2.1
1 2 3 4 5 | extension Data { var string: String? { return String(data: self, encoding: .utf8) } } |
1 2 3 4 5 | extension StringProtocol { var data: Data { return Data(utf8) } } |
1 2 3 4 5 | extension String { var base64Decoded: Data? { return Data(base64Encoded: self) } } |
游乐场
1 2 3 4 | let string ="Hello World" //"Hello World" let stringData = string.data // 11 bytes let base64EncodedString = stringData.base64EncodedString() //"SGVsbG8gV29ybGQ=" let stringFromData = stringData.string //"Hello World" |
1 2 3 4 5 6 | let base64String ="SGVsbG8gV29ybGQ=" if let data = base64String.base64Decoded { print(data) // 11 bytes print(data.base64EncodedString()) //"SGVsbG8gV29ybGQ=" print(data.string ??"nil") //"Hello World" } |
1 2 3 4 5 | 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 " |
有时,其他答案中的方法不起作用。在我的例子中,我正在用我的RSA私钥生成一个签名,结果是nsdata。我发现这似乎有效:
Objtovi-C
1 2 | NSData *signature; NSString *signatureString = [signature base64EncodedStringWithOptions:0]; |
迅捷
1 | let signatureString = signature.base64EncodedStringWithOptions(nil) |
总而言之,这里有一个完整的答案,对我很有用。
我的问题是当我使用
1 | [NSString stringWithUTF8String:(char *)data.bytes]; |
我得到的字符串是不可预测的:大约70%的字符串确实包含预期的值,但它常常是由
挖了几次以后,我换了
1 | [[NSString alloc] initWithBytes:(char *)data.bytes length:data.length encoding:NSUTF8StringEncoding]; |
每次都得到预期的结果。
使用swift 4.2,可以使用
1 | init?(data: Data, encoding: String.Encoding) |
Returns a
String initialized by converting given data into Unicode characters using a given encoding.
以下操场代码显示了如何使用它:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | 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("{ "firstName" : "John", "lastName" : "Doe" }") */ |