In Swift Data and NSData are ways to interact with raw binary data.
This article explains what that means, and how we can interact with “Data” in our Swift applications.
Data: Information processed or stored by a computer
Data types: A representation of the type of data that can be processed, for example Integer or String. Described by Apple as a byte buffer in memory
NSData: A static byte buffer that bridges to Data
NSData seem quite similar, in that both interact with raw binary data.
The major change between
NSData is the name, but some methods are different.
In fact you can access the raw memory contents of the elements that you are working with, using an unsafe pointer to do so. Both the
data types described can store raw
data more complex than simple Strings, Integers, Booleans, that is things like Images that might be used to write in and out of files, memory and databases. One use of these is the use of Core Data (that uses
Data as the Binary Data type); the massive advantage of this is that Core Data does not need to persist every possible type and the developer is responsible for encoding and decoding data while Core Data isn’t overloaded with a different type for every possible type.
There are differences between the types of data that can be Implemented in terms of mutability:
- Data: Swift-implemented
- immutable NSData
- mutable NSMutableData
- custom subclasses of NSData
- custom subclasses of NSMutableData
Data is a native Swift value type as it is a struct (as mentioned in the documentation). This means that
Data implements copy-on-write.
We can think of
Data as an updated version of
NSData for Swift, rather than relying on Objective-C code.
NSData is a class, and therefore is a reference type.
It can also be used with Objective-C code, and actually should probably only be used in this case.
Since you can cast too and from
NSData at will, you should do this when needed if you need to use Objective-C code.
Data from String
let data: Data? = str.data(using: .utf8) // optional Data
let dataStr: Data = Data(str.utf8) // Data
NSData we should note that we cannot use the same initialiser as above.
We can, of course, use an
NSString but it too does not have methods that exactly give the functionality that we might be interested in.
Data from NSData
We can, however, convert from
let dataStr: Data = Data(str.utf8)
let stringNS = NSData(data: dataStr)
This means that we can set up the
Data as shown above, and just deal with it from there through casting.
NSData from Data
Data? No problem: We can use the initializer for
init(reference reference; __ shared NSData).
This is implemented through taking the
NSData and then using the initializer:
let stringNS = NSData(data: dataStr)
let test = Data(referencing: stringNS)
Why value and why reference types
Looking through the Swift Evolution proposal (link below) there seemed to be an inherent problem with
NSData being a reference type (a class) particularly as the compiler did not give any warnings when the reference type embedded a value type, that is the underlying data would be shared and this would only be apparent at runtime.
And that is a BIG no from Us. Simon
NSData are relatively similar. I mean, yes, some of the methods on each differ. However, you would be well advised to choose (when you have the choice)
Data as the newer Swift type which also defines
Data as a value type.
There are some reasons that you might still need to use NSData, and for that you might cast your mind towards Core Data or other Objective-C functions.
Extend your knowledge
- The Swift Evolution proposals for Data are proposed HERE
The Twitter contact:
Any questions? You can get in touch with me here