41

I'm trying to create an NSData var from an array of bytes.

In Obj-C I might have done this:

NSData *endMarker = [[NSData alloc] initWithBytes:{ 0xFF, 0xD9 }, length: 2]

I can't figure out a working equivalent in Swift.

6 Answers 6

72

NSData has an initializer that takes a bytes pointer: init(bytes: UnsafeMutablePointer <Void>, length: Int). An UnsafePointer parameter can accept a variety of different things, including a simple Swift array, so you can use pretty much the same syntax as in Objective-C. When you pass the array, you need to make sure you identify it as a UInt8 array or Swift's type inference will assume you mean to create an Int array.

var endMarker = NSData(bytes: [0xFF, 0xD9] as [UInt8], length: 2)

You can read more about unsafe pointer parameters in Apple's Interacting with C APIs documentation.

Sign up to request clarification or add additional context in comments.

4 Comments

So that's what I would have thought too. But when I print that out in the debugger I get: <ff00>; and if I do more bytes I get the same thing, all 00 after the first byte.
Added type information to the array - it was sending an array of Int instead of an array of Byte.
Just to add, Byte is removed in swift1.2, use UInt8 instead.
I'm just learning Swift, so this is probably a dumb question. If I write the following: "_fileHandle!.write(NSData(bytes: UnsafePointer(byteData), length: byteLength) as Data)" then it works OK. But I'm worried that that this maybe involves creating a new copy of byteData, which is a 100 KB byte array. Surely not?
19
var foo : Byte[] = [0xff, 0xD9]

var data = NSData(bytes: foo, length: foo.count)

println("\(data)")

outputs: ff d9

var data = NSData(bytes: [0xFF, 0xD9] as Byte[], length: 2)

println("\(data)")

outputs: ff d9

Edit: Ah, you have to write 'as Byte[]', so then the results are the same


UPDATED for Swift 2.2

var foo:[UInt8] = [0xff, 0xD9]
var data = NSData(bytes: foo, length: foo.count)
print("\(data)")

outputs: ff d9

var data = NSData(bytes: [0xFF, 0xD9] as [UInt8], length: 2)
print("\(data)")

outputs: ff d9

2 Comments

Looks like you can't use Byte anymore in Swift 1.2. Instead of Byte[], write [Uint8]
No that's UInt8 (spelling)
19

You don't need to extend Data, in Swift 3 you can do this:

let bytes:[UInt8] = [0x00, 0x01, 0x02, 0x03]
let data = Data(bytes: bytes)
print(data as NSData)

Prints "<00010203>"

To get the byte array again:

let byteArray:[UInt8] = [UInt8](data)

1 Comment

Thanks. Anything changed in Swift 4?
8

For Swift 5 I have created another Data extension that works well.

extension Data {

    init<T>(fromArray values: [T]) {
        var values = values
        self.init(buffer: UnsafeBufferPointer(start: &values, count: values.count))
    }

    func toArray<T>(type: T.Type) -> [T] {
        let value = self.withUnsafeBytes {
            $0.baseAddress?.assumingMemoryBound(to: T.self)
        }
        return [T](UnsafeBufferPointer(start: value, count: self.count / MemoryLayout<T>.stride))
    }

}

Sample Usage

let data = Data(fromArray: [1, 2, 3, 4, 5])
let array = data.toArray(type: Int.self)
print(array)
// [1, 2, 3, 4, 5]

Comments

6

Swift 3 extension

extension Data {

    init<T>(fromArray values: [T]) {
        var values = values
        self.init(buffer: UnsafeBufferPointer(start: &values, count: values.count))
    }

    func toArray<T>(type: T.Type) -> [T] {
        return self.withUnsafeBytes {
            [T](UnsafeBufferPointer(start: $0, count: self.count/MemoryLayout<T>.stride))
        }
    }
}

Usage

let bytes:[UInt8] = [0x00, 0xf4, 0x7c]
let data = Data(fromArray: someBytes)
print(data as NSData)

let bytes = data.toArray(type: UInt8.self)
print(bytes)

Comments

2

Answer in Swift 5 is simple and not found here. Ran into this issue and found answer:

var bytes = [Int8](repeating: 0, count: 32)
let data = Data(bytes: bytes, count: bytes.count)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.