Skip to Content
Course content

69: Data and Its String/Array Conversions

Click on the "Edit" button in the top corner of the screen to edit your slide content.

Imagine you're sending a physical letter through the mail. The actual message—your thoughts, the words, the sentiment—is what you care about. But the post office doesn't deal in "sentiments." They deal in envelopes, stamps, and weight. To get your message from point A to point B, you have to pack that abstract idea into a physical object (the envelope) that fits their system. When your friend receives it, they perform the reverse process: they open the envelope and translate those physical ink marks back into a meaningful message in their head.

In Swift, Data is that envelope. A String is the message you want to send, but the network, the hard drive, and the Bluetooth chip don't understand "Strings." They only understand bytes—sequences of 0s and 1s. Data is essentially a wrapper around a collection of bytes (specifically UInt8 values) that allows Swift to move information around efficiently.

Packing your Strings into Bytes

When you want to turn a String into Data, you can't just "cast" it. You have to tell Swift how to encode it. Most of the time, you'll use UTF-8, which is the gold standard for the modern web. I've seen a few developers get tripped up here because they forget that this process can technically fail, although with UTF-8, it almost never does.

let secretMessage = "Meet me at the docks at midnight!"
// We use .data(using:) to convert the string to a Data object
if let data = secretMessage.data(using: .utf8) {
    print("Successfully packed the message into \(data.count) bytes.")
}

Notice that data(using:) returns an optional. It's Swift's way of saying, "I'll try to encode this, but if you give me a weird encoding that doesn't support these characters, I'm giving you nil."

Unpacking Bytes back into Text

Now, let's say you've just downloaded a small configuration file or received a packet from a server. You've got a Data object, but it looks like gibberish if you print it. You need to translate those bytes back into a human-readable string.

let receivedData = Data([77, 101, 101, 116]) // Represents "Meet" in ASCII/UTF-8

if let decodedString = String(data: receivedData, encoding: .utf8) {
    print("The message is: \(decodedString)")
} else {
    print("The data wasn't valid UTF-8. Someone sent us garbage.")
}

I always recommend using if let or guard here. If you try to force-unwrap a data conversion and the bytes are corrupted, your app will crash. It's not worth the risk just to save a line of code.

When you need to touch individual bytes

Sometimes, you don't want a string. Maybe you're writing a custom file parser or working with a binary protocol where the third byte represents a version number and the fourth byte is a flag. In those cases, you want to treat Data like an array of numbers.

Because Data conforms to RandomAccessCollection, you can actually iterate over it or access indices directly. But if you specifically need a standard Swift array of unsigned 8-bit integers ([UInt8]), you can initialize one directly from the data.

let rawBytes = Data([0x48, 0x49]) // 'H' and 'I' in hex
let byteArray = [UInt8](rawBytes)

print(byteArray[0]) // Output: 72

Going the other way is just as easy. If you have an array of bytes from some low-level API, you can just wrap them in a Data object: let data = Data(byteArray). I find it helpful to think of Data as the "transport" format and [UInt8] as the "manipulation" format.




📋 Practical Task

The Secret Message Byte-Parser

You've intercepted a transmission from a mysterious source. The data is arriving as an array of bytes, but the first two bytes are just "header" bytes (metadata) and should be ignored. The remaining bytes contain a hidden message encoded in UTF-8.

Your Task: Write a function called decodeTransmission(bytes: [UInt8]) that:

  • Takes an array of UInt8 as input.
  • Removes the first two elements of the array.
  • Converts the remaining bytes into a Data object.
  • Converts that Data object into a UTF-8 String.
  • Returns the decoded string, or "Invalid Transmission" if the conversion fails.

Test your function with this input:
let transmission = [0xAA, 0xBB, 0x53, 0x77, 0x69, 0x66, 0x74, 0x20, 0x69, 0x73, 0x20, 0x61, 0x77, 0x65, 0x73, 0x6f, 0x6d, 0x65]
(The result should be: "Swift is awesome")

Rating
0 0

There are no comments for now.

to be the first to leave a comment.