Photo by Markus Spiske on Unsplash

Back in 1936 the computer scientist Alan Turing invented a model of a computational device later known as The Turing Machine. This machine did simple operations and had a state. This state was actually a piece of data, and the machine was “running” algorithms to perform operations over that data.

All that a computer program does is actually just data receiving, sending and processing. Data is that unit with which our code works. Even operations which don’t look like data processing, for example, showing the user interface or handling button clicks, are actually sending packets of data to an API and receiving responses.

Now, in 2020, we still work with algorithms and data. What became more complex are the data structures and, as a result, the conversions between them. Let’s have a look at the most popular Swift data types, structures and classes and find (or write) functions converting one into another.

A note about Swift types

Swift inherited its types from Objective-C, but Swift has a different naming convention for complex types. Classes from the Foundation framework typically start with the prefix NS (from NextStep). In Swift the NS is usually dropped and instead of NSString you have String and Data instead of NSData.

In some cases it’s kind of renaming, but not everywhere. TheString class doesn’t have access to all NSString methods. It’s not an alias, it’s a wrap around NSString. But Swift allows to make a fast conversion if you need to access properties and methods of the original NSString class:

let str: String = "Some String"
let nsstr = str as NSString

Such conversions never fail, that’s why you don’t need to use ! or ? after as.

Data to String and back

In the C programming language Data and String were the same data type, and they were the same as arrays of bytes. Modern Strings are not just buffers of data, they also have information about encoding and many useful methods.

At the same time, Data (aka NSData) can logically contain text, which means there should be a way to convert it to String (aka NSString) and back.

I use exclamation marks for the sake of simplicity. Thedata method returns optional Data objects. Read here how to deal with optionals in a proper way.

Numbers to String and back

Another popular conversion is numbers (Int, Double and others) to String and back.

The easiest (but not always the best) way to convert number to String is String interpolation. In other words, inserting variables (or constants) to strings using \() constructions. The disadvantage of this method is that you can’t format it. For example, if you want to use a currency formatting, it’s better to use String.format:

Format specifiers in Swift are inherited from Objective-C, and format specifiers in Objective-C are inherited from the legendary printf function family in C. You can find a list of Swift format specifiers here.

Another important note: when you turn String into Int or Double you get an optional value. It makes sense, because Int("a") should return nil. Int("1.5") will also return nil, not 1 or 2.

String to Dictionary and Array and back

This is a big topic, because it depends on the String format. The 3 most popular formats are JSON, XML and YAML.

  • JSON JavaScript Object Notation. A variation of JavaScript language, or more precisely of the part of JavaScript language responsible for describing objects and arrays. An interesting fact about JSON is that it can be pasted into JavaScript code and parsed by web browsers or another JavaScript engines.
  • XMLeXtensible Markup Language. It’s a popular language for creating layouts of web pages and UIs. It’s the main format of Universal Windows Platform layouts, Android layouts and a close relative of HTML (HyperText Markup Language) and kind of a parent of PLIST (Property List) format actively used for iOS and macOS development.
  • YAML Yet Another Markup Language. Another popular language to represent data. Often used for configuration files, for example, in Flutter.

These 3 languages look very different, but they have some things in common:

  1. They are text strings.
  2. Swift dictionaries and arrays can be serialised into them and deserialised from them as long as each data type inside dictionaries and arrays is serialisable.

JSON

The easiest case is JSON. All modern languages support JSON as it’s the most common way of information exchange with server APIs.

This example shows how to convert a JSON String to Dictionary and back. In the end it prints this:

{
"key1" : "val1",
"arr" : [
1,
2,
3
],
"key2" : "val2"
}

It’s easy to see that it’s the same data structure as we provide, but formatted differently . If you need to prepare data for sending to the API, you’d better remove the .prettyPrinted option to get a more optimised (but less human readable) output.

XML

The next is XML. Swift has the internal class XMLParser, but it doesn’t make conversions. It’s very powerful, but very uncomfortable to use. For example, that’s how we can parse a simple XML String:

The output of this code is:

Found element parent with attributes [:]Found element child with attributes ["attr": "attr"]

As you can see, it parses XML correctly, but it doesn’t create a Dictionary or an Array object.

To get a dictionary, you need an external library. For example, SWXMLHash. This library is a wrapper around XMLParser (aka NSXMLParser), but it also makes conversion, which is exactly what we need.

You can add it with Cocoapods:

pod 'SWXMLHash'

If you’re not familiar with Cocoapods or you want to find another useful libraries for your project, you can read this article.

Then you parse XML document with just one line of code:

let xmlDict = SWXMLHash.parse(xml)

How to write XML? The easiest way is to generate String with String.format, but you may have problems with some symbols… you’ll need to escape them. Has anyone done it for us?

I didn’t find any modern solution. All the libraries are either deprecated or do something different. But I found a post here. It’s in Objective-C and doesn’t handle all the cases, so I wrote an updated version:

XML can have only one root element, that’s why we need to provide it specifically. See the example below:

let dict: [String: Any] = [
"child1": [1, 2, 3],
"child2": "Hello, world",
"child3": [
["a": "b"],
"cd",
5
]
]
let xml = convertDictionaryToXML(dictionary: dict, startElement: "root", isFirstElement: true)
print(xml)

The output will be the following:

<?xml version="1.0" encoding="utf-8"?>
<root>
<child2>Hello, world</child2>
<child3>
<a>b</a>
</child3>
<child3>cd</child3>
<child3>5</child3>
<child1>1</child1>
<child1>2</child1>
<child1>3</child1>
</root>

This is a valid XML. As a side note I will mention that the elements of arrays are ordered, but the keys in the dictionary are not. This is a common rule for all programming languages.

YAML

Swift doesn’t provide an integrated way to create or parse YAML. But there are good libraries for it. For example, Yams.

Include it with Cocoapods:

pod 'Yams'

Import it:

import Yaml

And use:

let strYAML: String? = try? Yams.dump(object: dictionary)let loadedDictionary = try? Yams.load(yaml: mapYAML) as? [String: Any]

Numeric conversions

Swift makes it easy to convert different numeric types.

The problem is that conversion from Double (and Float) to Int will always ignore the decimal part. To fix this issue and get a mathematically correct rounding, use the round function on Double before converting it to Int:

Converting Bool

Bool or Boolean is a logical type, which can have only two values: true and false. true in Objective-C is also known as YES and false is NO. Even if you program in Swift, you may see YES and NO in PLIST files and Objective-C libraries.

Usually true is represented in memory as 1 and false as 0. In C, for example, you can write if (1) { ... } and while (1) { ... } makes an infinite loop unless you terminate it with break or return. JavaScript offers the conception of truth-y and false-y values. For example, 1 is truth-y and nil is false-y.

Swift needs an explicit conversion to Bool for these cases. Constructions like let b = Bool(1) will cause a warning. And in my opinion it’s the right thing. Because I don’t know if -1 is truth-y or false-y. Different programmers will give different answers. And different programming languages will interpret it differently.

Many APIs return 0 for success and non-0 value for errors. The WIN32 API defines a constant S_OK, which is 0. And if you write:

if (some_call()) {
// ...
}

the inner code will never be executed if some_call returns S_OK.

I’m writing all this to say that all conversions between boolean values and numeric values should be forbidden to avoid all this mess.

On the other hand, conversions between Bool and String make sense.

As you can see from the example above, Swift considers only “true” and “false” as valid boolean strings. That’s why, working in Swift, you should serialise Bool this way.

If you use external APIs, for example, REST API, you should check how boolean values are presented in the documentation and make explicit conversions. For example:

Date and Time

For both date and time Swift offers the data type Date. It’s easy to confuse with Data, but it’s totally different.

Technically, Date is a combination of two values:

  • Timestamp
  • Time zone

When we talk about dates, it makes sense to convert it to (from) two data types — Double and String. Double (aka TimeInterval) is the way Swift represents timestamps (amount of seconds since Epoch, 1 January 1970). And String has many purposes, starting with showing date and/or time to the user and ending with sending them to the server in ISO-8601 format.

The example above shows how Date can be converted into timestamp or one of possible strings.

The opposite conversion is also possible. For example:

As you can probably guess, objects date1, date2 and date3 refer to the same date and time (except milliseconds, they will be different).

Conclusion

Swift is a strictly typed programming language, that’s why even simple data conversions need to be made explicitly. We reviewed conversions between the most common data types and data formats used in modern programming.

Happy coding and see you next time!

Game and software developer with more than 15 years experience. Founder and CEO at Mariposa Studios, freelancer.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store