如何在 Swift 中初始化来自 NSData 的字符串

我一直在尝试用 Swift 初始化来自 NSData的字符串。

NSString Cocoa 文档中,苹果说你必须这样做:

 init(data data: NSData!, encoding encoding: UInt)

然而,苹果没有包括任何例子的使用或在哪里放置的 init

我正在尝试将下面的代码从 Objective-C 转换为 Swift

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

我已经尝试了很多可能的语法,比如下面的语法(当然它不起作用) :

var string:NSString!
string = init(data: fooData,encoding: NSUTF8StringEncoding)
145688 次浏览

下面是初始化 NSString的方法:

Swift 2.X 或更高版本

let datastring = NSString(data: fooData, encoding: NSUTF8StringEncoding)

迅捷3或更新:

let datastring = NSString(data: fooData, encoding: String.Encoding.utf8.rawValue)

这个 doc 解释了语法。

import Foundation
var string = NSString(data: NSData?, encoding: UInt)

这是所需的实现代码:

在 Swift 3.0中:

var dataString = String(data: fooData, encoding: String.Encoding.utf8)

或者只是

var dataString = String(data: fooData, encoding: .utf8)

老版迅捷:

在 Swift 2.0中:

import Foundation


var dataString = String(data: fooData, encoding: NSUTF8StringEncoding)

在 Swift 1.0中:

var dataString = NSString(data: fooData, encoding:NSUTF8StringEncoding)

Swift 2.0

似乎 Swift 2.0在导入 Foundation时实际上引入了 String(data:encoding:)作为 String 扩展。奇怪的是,我没有找到任何地方记录这一切。

(pre Swift 2.0)轻量级扩展

这里有一个不使用 NSString的可复制粘贴的小扩展,让我们切断中间人。

import Foundation


extension NSData
{
var byteBuffer : UnsafeBufferPointer<UInt8> { get { return UnsafeBufferPointer<UInt8>(start: UnsafeMutablePointer<UInt8>(self.bytes), count: self.length) }}
}


extension String
{
init?(data : NSData, encoding : NSStringEncoding)
{
self.init(bytes: data.byteBuffer, encoding: encoding)
}
}


// Playground test
let original = "Nymphs blitz quick vex dwarf jog"
let encoding = NSASCIIStringEncoding


if let data = original.dataUsingEncoding(encoding)
{
String(data: data, encoding: encoding)
}

这也使您能够访问序列类型的 data.byteBuffer,因此您可以对序列执行的所有这些很酷的操作也都可以工作,例如对校验和执行 reduce { $0 &+ $1 }操作。

笔记

在我之前的编辑中,我使用了这种方法:

var buffer = Array<UInt8>(count: data.length, repeatedValue: 0x00)
data.getBytes(&buffer, length: data.length)
self.init(bytes: buffer, encoding: encoding)

这种方法的问题在于,我要将信息的副本创建到一个新的数组中,因此,我要复制字节的数量(特别是: encoding size * data.length)

目标 C

NSData *myStringData = [@"My String" dataUsingEncoding:NSUTF8StringEncoding];
NSString *myStringFromData = [[NSString alloc] initWithData:myStringData encoding:NSUTF8StringEncoding];
NSLog(@"My string value: %@",myStringFromData);

斯威夫特

//This your data containing the string
let myStringData = "My String".dataUsingEncoding(NSUTF8StringEncoding)


//Use this method to convert the data into String
let myStringFromData =  String(data:myStringData!, encoding: NSUTF8StringEncoding)


print("My string value:" + myStringFromData!)

Http://objectivec2swift.blogspot.in/2016/03/coverting-nsdata-to-nsstring-or-convert.html

另一个基于扩展的答案(我在 Java 中很怀念这个) :

extension NSData {
func toUtf8() -> String? {
return String(data: self, encoding: NSUTF8StringEncoding)
}
}

然后你可以使用它:

let data : NSData = getDataFromEpicServer()
let string : String? = data.toUtf8()

注意,字符串是可选的,初始 NSData可能不能转换为 Utf8。

自从第三版 Swift 以来,你可以做到以下几点:

let desiredString = NSString(data: yourData, encoding: String.Encoding.utf8.rawValue)

类似于 Sunkas 的建议。