How to Convert String Array to NSData, NSData to String Array?
I tested this in 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
}
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]
}
For a direct answer to your question, you could ask each string in your array for its thisString.dataUsingEncoding(_:)
and append the result to an NSMutableData
instance until you're all done.
let stringsData = NSMutableData()
for string in strings {
if let stringData = string.dataUsingEncoding(NSUTF16StringEncoding) {
stringsData.appendData(stringData)
} else {
NSLog("Uh oh, trouble!")
}
}
Of course this doesn't help you if you want to separate the strings later, so what we really need to know is how / in what environment do you intend to consume this data on the other end of your connection? If the other end uses Cocoa as well, consider just packaging it as a PLIST. Since NSString
, NSArray
, and NSData
are all property list types, you can just archive your NSArray
of NSString
instances directly:
let arrayAsPLISTData = NSKeyedArchiver.archivedDataWithRootObject(strings)
...then transfer the resulting NSData
instance to the Cocoa-aware destination and then:
if let newStrings: [String] = NSKeyedUnarchiver.unarchiveObjectWithData(arrayAsPLISTData) as? [String] {
// ... do something
}