Data vs [UInt8]
Asked Answered
S

2

9

Swift offers both Data and [UInt8] types, which do a very similar thing.

  • What are the differences between the two?
  • When designing new API's, what's the preferred type?
Schreib answered 5/10, 2016 at 11:55 Comment(1)
I'd say that Data (~NSData) are objects and provide a lot methods that could be useful. But it depends if you need them or not.Synge
E
6

[UInt8] is essentially a byte array, a byte (as I'm sure you know), is comprised of 8 bits. Whilst NSData isn't simply a byte array, deep down it's underlying structure is based off one. You can easily convert between them using methods such as data.bytes, for example.

In terms of designing APIs, I would personally recommend you design them with NSData simply because of all the extra functionality it offers over a simple byte array. Apple has already done a lot of the legwork for you, so why do it again yourself?

Enthrall answered 5/10, 2016 at 12:8 Comment(11)
Is Data something we are encouraged to use or just to interface with ObjC parts? Do you have popular libraries that use Data vs [UInt8]?Schreib
What about Linux apps that don't use ObjC parts? Is Data popular for those?Schreib
NSData is simply the iOS/OSX way of representing binary data. The data actually exchanged between the app and your backend is usually a base64 encoded string. NSData can easily be converted to this using data.base64EncodedStringWithEncoding(NSUTF8StringEncoding)Enthrall
I'm not on iOS, but instead work with some C APIs and other non-iOS Swift APIs. I wonder whether Data is popular outside the iOS/macOS world, or whether it's just used in conjunction with iOS/macOS/ObjC.Schreib
If you are working with C then I would use the byte array. NSData is an apple wrapper around this which extends its functionality. If you're not using iOS/OSX you won't have access to this class anyway.Enthrall
The Foundation library is available on Linux as well :-) In the end, I don't think it matters too much. Will try with Data, and revert to [UInt8] when this fails.Schreib
Sounds like a good approach to me! I wasn't aware Foundation was available on Linux. Hey, learn something new every day...Enthrall
In your case, if Foundation is available and give some useful methods, you could use NSData, but if you do some "simple" stuff, you can keep using [UInt8].Synge
It's only a light version, but Data is in it – github.com/apple/swift-corelibs-foundationSchreib
Seems like Data does not offer everything that [UInt8] offers: stackoverflow.com/questions/40190415Schreib
It looks like Apple has made a concerted effort to switch from [UInt8] to Data, at least within the Swift Protobuf project: github.com/apple/swift-protobuf/issues/129 github.com/apple/swift-protobuf/pull/134Kinglet
L
3

I prefer using Data for most things, but [UInt8] has one distinct advantage: you can pass it directly to functions requiring pointers to the bytes like C functions, whereas for Data you have to do a bunch more gymnastics. The code below demonstrates the difference for both immutable and mutable arrays and Data objects.

func takesAPointer(_ p: UnsafePointer<UInt8>) {
    // ...
}

let a: [UInt8] = [1, 2, 3]
takesAPointer(a)
let d = Data([1, 2, 3])
d.withUnsafeBytes {
    let p = $0.bindMemory(to: UInt8.self).baseAddress!
    takesAPointer(p)
}

func takesAMutablePointer(_ p: UnsafeMutablePointer<UInt8>) {
    // ...
}

var b: [UInt8] = [1, 2, 3]
takesAMutablePointer(&b)
var e = Data([1, 2, 3])
e.withUnsafeMutableBytes {
    let p = $0.bindMemory(to: UInt8.self).baseAddress!
    takesAMutablePointer(p)
}
Lid answered 20/9, 2020 at 6:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.