如何将字符串数组转换为NSData,NSData转换为字符串数组?

20
我想将[String]转换为NSData以进行蓝牙连接。
我知道如何将String转换为NSData/NSData转换为String。
// String -> NSData
var str: String = "Apple";
let data: NSData = str.dataUsingEncoding(NSUTF8StringEncoding)!

// NSData -> String
var outStr: String = NSString(data:data, encoding:NSUTF8StringEncoding) as! String

然而,我该如何转换,

// [String] -> NSData ???
let strs: [String] = ["Apple", "Orange"]

这是将 [UInt8] <--> NSData 转换的示例

https://gist.github.com/nolili/2bf1a701df1015ed6488

我想将 [String] <--> NSData 转换

// [String] -> NSData ??? Is it correct???
var strs: [String] = ["Apple", "Orange"]
let data2 = NSData(bytes: &strs, length: strs.count)

// NSData -> [String] ... please teach me..
3个回答

23

Swift 4.2

[String] -> JSON -> Data

func stringArrayToData(stringArray: [String]) -> Data? {
  return try? JSONSerialization.data(withJSONObject: stringArray, options: [])
}

Data -> JSON -> [String]

func dataToStringArray(data: Data) -> [String]? {
  return (try? JSONSerialization.jsonObject(with: data, options: [])) as? [String]
}

这是完美的答案! - Manish

12

对于你的问题,你可以直接询问数组中的每个字符串关于它的 thisString.dataUsingEncoding(_:) ,并将结果添加到一个 NSMutableData 实例中,直到所有操作都完成。

let stringsData = NSMutableData()
for string in strings {

    if let stringData = string.dataUsingEncoding(NSUTF16StringEncoding) {

        stringsData.appendData(stringData)

    } else {

        NSLog("Uh oh, trouble!")

    }

}

当然,如果您想稍后分离字符串,这对您没有帮助,因此我们真正需要知道的是,在连接的另一端,您打算在什么环境中使用这些数据?如果另一端也使用Cocoa,请考虑将其打包为PLIST。由于NSString、NSArray和NSData都是属性列表类型,因此您可以直接归档NSString实例的NSArray:

let arrayAsPLISTData = NSKeyedArchiver.archivedDataWithRootObject(strings)

然后将生成的NSData实例转移到Cocoa-aware目标,然后执行以下操作:


if let newStrings: [String] = NSKeyedUnarchiver.unarchiveObjectWithData(arrayAsPLISTData) as? [String] {

    // ... do something

}

谢谢您的回复,很抱歉我回复晚了... 我想通过BLE连接将[String]发送到其他设备。 当我们通过BLE发送一些东西时,我们使用“writeValue”方法。 peripherl.writeValue(data: NSData, forCharacteristic: characteristic, type: 响应类型)。 - ketancho
我使用了NSKeyedUnarchiver,它很有效!非常感谢。然而,我不知道在通过BLE连接发送消息时将NSData转换的最佳方法是什么。 - ketancho
那仍然不能回答我的问题。BLE设备究竟如何处理这些数据?你在使用哪种编程环境/语言/设备来处理这些字符串数据?这些是我们必须知道的关键信息,以便确定如何回答你的问题,让你能够理解和应用。 - Joshua Nozzi
感谢您的评论。编程环境是XCode 7.0,语言是Swift 2.0。我想从iPhone A发送消息到iPhone B。iPhone A发送消息:[String],通过函数writeValue(data: NSData, forCharacteristic: characteristic, type: responseType)将NSData转换后发送。然后,iPhone B从函数peripheralManager(peripheral: CBPeripheralManager, didReceiveWriteRequests requests: [CBATTRequest])接收NSData,将requests[n]从NSData转换为[String]并更新消息区域。 - ketancho

5

我在iOS 9上进行了测试

func test() {
    let originalStrings = ["Apple", "Pear", "Orange"]
    NSLog("Original Strings: \(originalStrings)")

    let encodedStrings = stringArrayToNSData(originalStrings)
    let decodedStrings = nsDataToStringArray(encodedStrings)
    NSLog("Decoded Strings: \(decodedStrings)")
}

func stringArrayToNSData(array: [String]) -> NSData {
    let data = NSMutableData()
    let terminator = [0]
    for string in array {
        if let encodedString = string.dataUsingEncoding(NSUTF8StringEncoding) {
            data.appendData(encodedString)
            data.appendBytes(terminator, length: 1)
        }
        else {
            NSLog("Cannot encode string \"\(string)\"")
        }
    }
    return data
}

func nsDataToStringArray(data: NSData) -> [String] {
    var decodedStrings = [String]()

    var stringTerminatorPositions = [Int]()

    var currentPosition = 0
    data.enumerateByteRangesUsingBlock() {
        buffer, range, stop in

        let bytes = UnsafePointer<UInt8>(buffer)
        for var i = 0; i < range.length; ++i {
            if bytes[i] == 0 {
                stringTerminatorPositions.append(currentPosition)
            }
            ++currentPosition
        }
    }

    var stringStartPosition = 0
    for stringTerminatorPosition in stringTerminatorPositions {
        let encodedString = data.subdataWithRange(NSMakeRange(stringStartPosition, stringTerminatorPosition - stringStartPosition))
        let decodedString =  NSString(data: encodedString, encoding: NSUTF8StringEncoding) as! String
        decodedStrings.append(decodedString)
        stringStartPosition = stringTerminatorPosition + 1
    }

    return decodedStrings
}

谢谢Robert,抱歉回复晚了。你的代码在我的环境中也起作用了。非常感谢你。 - ketancho
不客气,@ketancho,这个答案够好了吗?(这会是我的第一个 :-)) - Verticon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接