
What is bitmask?
Bitmasks are used to access mask-specific bits in data. The main use case for that is to store and manage multi-choice structures.
We know that Swift Int16 is a 16-bit data type (duh). Now Let’s take one Int16 variable, and represent its data with bits:
So instead of looking at it as one INT, we can look at it as 16 bits, when each of the bits represents ON or OFF values for basically anything you want.
Let’s say you have a pizza delivery app, in which you want to manage the toppings. You can store 16 options of toppings with only one Int16.
As can be seen in the example above, the Int16 variable holds data for 16 types of toppings per pizza. 2 bits are turned on — the Olives and the Extra Cheese (I know, boring choice). Since it’s only an Int variable it cannot hold the actual names of the toppings, only what bits are turned on and off. However, there is a way of holding the names quite easily.
Objective C Way
In Objective C we used to have NS_OPTIONS macro. We then define a new Integer-based type and the list of options we want as well.
For each option, we need to define what bit is turned on or in other words, how to “mask” the bits.
https://gist.github.com/AviTsadok/de3eddf40451c25486acca1491f0df66
On this type, we can use OR and AND operations, to support multi-selection of options.
https://gist.github.com/AviTsadok/fcec9d2e87f183d9766a83390f118b97
Which is similar to:
00000001 // Deleted | 00000010 // Archived -------------------- = 00000011 // Deleted | Archived
Quite simple, isn’t it?
But in swift we have a simpler and more elegant way of doing things.
OptionSet Protocol — Swift Solution
The iOS SDK contains almost 400 (!) types which conform to the OptionSet protocol. One popular example is the UIView auto resizing mask:
view.autoresizingMask = .flexiableHeight
You can also set multiple values to an OptionSet:
view.autoresizingMask = [.flexibleHeight ,.flexibleWidth]
Or without any values:
view.autoresizingMask = []
But it also really easy to create an OptionSet type of your own:
https://gist.github.com/AviTsadok/bad97d9e6ad9a28a874ca7eadda23ca3
And you can use “contains” to check if the option is contained inside your variable:
if toppings.contains(.bacon) { // do something }
Int / Int8 / Int16 / Int32 -> FixedWidthInteger
So what types can you use for OptionSet? Basically, any type that conforms to FixedWidthInteger.
(U)Int
(U)Int8
(U)Int16
(U)Int32
(U)Int64
Note: On 32-bit devices (Which are quite rare today), the “regular” Int is actually Int32, and on 64-bit devices, Int is Int64 bit.
Summary
OptionSet is a great and elegant way to deal with Multi-Choice types. This can be anything from Pizza toppings to days of the week, to forms. It’s best practice to choose the right Int size for efficiency, but it’s applicable to every aspect of programming.