NSData to [Uint8] in Swift

SwiftNsdata

Swift Problem Overview


I couldn't find a solution to this problem in Swift (all of them are Objective-C, and they deal with pointers which I don't think exist in Swift in the same form). Is there any way to convert a NSData object into an array of bytes in the form of [Uint8] in Swift?

Swift Solutions


Solution 1 - Swift

You can avoid first initialising the array to placeholder values, if you go through pointers in a slightly convoluted manner, or via the new Array constructor introduced in Swift 3:

Swift 3
let data = "foo".data(using: .utf8)!

// new constructor:
let array = [UInt8](data)

// …or old style through pointers:
let array = data.withUnsafeBytes {
    [UInt8](UnsafeBufferPointer(start: $0, count: data.count))
}
Swift 2
Array(UnsafeBufferPointer(start: UnsafePointer<UInt8>(data.bytes), count: data.length))

Solution 2 - Swift

Swift 5 Solution

Data to [bytes]

extension Data {
    var bytes: [UInt8] {
        return [UInt8](self)
    }
}

[bytes] to Data

extension Array where Element == UInt8 {
    var data: Data {
        return Data(self)
    }
}

Solution 3 - Swift

It's funny but exist more simple solution. Works in Swift 3. Surely. I've used this today.

data: Data // as function parameter    
let byteArray = [UInt8](data)

That's all! :) NSData easily bridged to Data.

UPDATE: (due to Andrew Koster comment)

Swift 4.1, Xcode 9.3.1

Just has been rechecked - all works as expected.

if let nsData = NSData(base64Encoded: "VGVzdFN0cmluZw==", options: .ignoreUnknownCharacters) {
let bytes = [UInt8](nsData as Data)
print(bytes, String(bytes: bytes, encoding: .utf8))

Output: [84, 101, 115, 116, 83, 116, 114, 105, 110, 103] Optional("TestString")

Solution 4 - Swift

You can use the getBytes function of NSData to get the byte array equivalent.

As you did not provide any source code, I will use a Swift String contents that has been converted to NSData.

var string = "Hello World"
let data : NSData! = string.dataUsingEncoding(NSUTF8StringEncoding)
    
let count = data.length / sizeof(UInt8)
    
// create an array of Uint8
var array = [UInt8](count: count, repeatedValue: 0)
    
// copy bytes into array
data.getBytes(&array, length:count * sizeof(UInt8))
    
println(array)

Swift 3/4

let count = data.length / MemoryLayout<UInt8>.size
      
// create an array of Uint8
var byteArray = [UInt8](repeating: 0, count: count)
// copy bytes into array
data.getBytes(&byteArray, length:count)

Solution 5 - Swift

Swift 3/4

let data = Data(bytes: [0x01, 0x02, 0x03])
let byteArray: [UInt8] = data.map { $0 }

Solution 6 - Swift

You can try

extension Data {
func toByteArray() -> [UInt8]? {
    var byteData = [UInt8](repeating:0, count: self.count)
    self.copyBytes(to: &byteData, count: self.count)
    return byteData
  }
}

Solution 7 - Swift

swift 4 and image data to a byte array.

 func getArrayOfBytesFromImage(imageData:Data) ->[UInt8]{

    let count = imageData.count / MemoryLayout<UInt8>.size
    var byteArray = [UInt8](repeating: 0, count: count)
    imageData.copyBytes(to: &byteArray, count:count)
    return byteArray

}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBowen SuView Question on Stackoverflow
Solution 1 - SwiftArkkuView Answer on Stackoverflow
Solution 2 - SwiftMaorView Answer on Stackoverflow
Solution 3 - SwiftsVdView Answer on Stackoverflow
Solution 4 - SwiftChristian AbellaView Answer on Stackoverflow
Solution 5 - SwiftAl ZonkeView Answer on Stackoverflow
Solution 6 - SwiftRachit AgarwalView Answer on Stackoverflow
Solution 7 - SwiftPathak AyushView Answer on Stackoverflow