Taming Foundation Constants into Swift Enums

For most of Cocoa, Apple has done a nice job of wrapping the APIs in native Swift entities. In particular, sets of constants that exist in NS_ENUM enumerations are imported as Swift enums with associated raw values. The situation is a little different when it comes to Foundation. In Foundation, many of the constants are not gathered into C enums and so they are not imported into Swift as nicely.

In this post I will look at what code is necessary to wrap up Foundation constants as a Swift enum and then I will introduce a simple tool to automate the code generation.

A Naïve First Attempt

I first became aware of this issue when I was writing some code to try to make the Keychain a little more palatable to use in Swift. I’ll use as an example throughout this post the manifest constants for the kSecAttrAccessible attribute in a keychain item. These are defined in SecItem.h as:

Although it is not apparent from these declarations, the underlying type of these constants is CFStringRef.

A first attempt to wrap these values in a Swift enum might look something like this.

Unfortunately this does not work, because the raw values of enum cases must be literals. I could have determined the values of the constants and explicitly equated these with the case values, but that would break in the (albeit unlikely) even of the value of a constant changing in some future version of the OS.

Conforming to RawRepresentable

A better solution is to have the enum conform to RawRepresentable. For Swift 1.1, the RawRepresentable protocol is defined as:

An initializer must be provided to create a enum from a rawValue and a computed property to perform the opposite conversion. In our example enum this would look something like this.

Other Nice Extensions

It can often be useful to be able to print the symbol for an enum (not it’s raw value) both during debugging and when presenting error information to the user. This can be achieved by extending the enum to conform to Printable.

Finally it would also be nice to be able to enumerate all the values of the enum. This can be done the extending the enum with an allValues array.

Automating the Procedure: enumtool

At this point we have a really nice Swift enum that wraps the Foundation constants, but what a lot of boilerplate code! Let’s face there is nothing more soul-destroying then spending hours cranking out boilerplate.

To automate this process, I created a little command line tool, written in swift and I have made it available on GitHub.

If the constants in the above example had been extracted, one per line, into a file called SecAttrAccessible.txt running enumtool as follows would create all the code in this article.

More information about enumtool can be found at the enumtool GitHub repository. I hope it may be of some use to you.


Posted in Swift | Leave a comment

Swift Parameter Labels

I am guessing early on in the development of the Swift language the relationship between a function declaration’s parameter labels and whether they need to be included in a call was much more forward.

Maybe it looked something like this.

Declaration Call Comment
func foo(x: Int) foo(2) Omit label
func foo(#x: Int) foo(x:2) Use label
func foo(_ x: Int) foo(2) or foo(x:2) Label optional
func foo(bar x: Int) foo(bar:2) Use external label

But then they decided that to make Swift play nice with Cocoa that labels would be required by default in classes, but not in standalone functions. As long as it wasn’t the first parameter in a member function, in which case the label was to be omitted. Unless it was an init in which case all labels were required. Oh, and if it had a default value, whether it is a standalone function or a member function the label was to be required.

When all was said and done, we were left the situation as depicted by the binary decision tree below.
Perhaps something more straightforward could have been devised?

labels_1.1


Posted in Swift | Leave a comment

Swift Standard Libraries: Sequence and Collection Functions

In the last post in this series, I took at look at the protocols that Swift uses to define generators, sequences and collections. In this post I am going to present examples of using the Standard Library Functions that operate on these types. I’ll run through them in alphabetical order.

Throughout this post I will use “a SequenceType” as a shorthand for “an object conforming to SequenceType protocol” and similar shorthand for other type-like protocols.

I have purposely left out the function definitions. Click on the swifter links to see the gory details. In the playground for the post you can also option-click.

So without further ado let’s get going.

advance

Advances an index by a given number of elements.

advance reference on Swifter

contains

Determines if a SequenceType contains an element

or contains an element that satisfies a predicate

contains reference on Swifter

count

Counts the number of elements in a range

count reference on Swifter

countElements

Counts the number of elements in a CollectionType

countElements reference on Swifter

distance

The distance in elements between two ForwardIndexTypes

distance reference on Swifter

dropFirst

Returns the slice obtained by dropping the first element of a sequence

dropFirst reference on Swifter

dropLast

Returns the slice obtained by dropping the first element of a sequence

dropLast reference on Swifter

enumerate

Prints

enumerate reference on Swifter

equal

Tests two sequences for equality

equal reference on Swifter

extend

Extends a mutable sequence

extend reference on Swifter

filter

Filters a sequence based on a predicate

filter reference on Swifter

first

Returns the first element of a collection

first reference on Swifter

indices

Returns the range of valid indices for a collection

indices reference on Swifter

insert

Inserts a new element into a RangeReplaceableCollectionType

insert reference on Swifter

isEmpty

Returns true if a collection contains no elements

isEmpty reference on Swifter

join

Returns a collection formed by placing a separator between each element of a sequence

join reference on Swifter

last

Returns the last element of a collection (with a BidirectionalIndexType) or nil

last reference on Swifter

lazy

Will be handled in a future post

map

Returns the array generated by applying a function to each element of an array

map reference on Swifter

maxElement

Returns the maximum element of a sequence

maxElement reference on Swifter

minElement

Return the minimum element of a sequence

minElement reference on Swifter

prefix

Will be handled in a future post. Operates on a Sliceable.

reduce

Accumulates the result of a function on each element of sequence

reduce reference on Swifter

removeAll

Remove all elements from a RangeReplaceableCollectionType, optionally requesting the storage capacity be preserved.

removeAll reference on Swifter

removeAtIndex

Remove and return an element from a RangeReplaceableCollectionType

removeAtIndex reference on Swifter

removeLast

Remove and return the last element from a nonempty RangeReplaceableCollectionType

removeLast reference on Swifter

removeRange

Remove elements within a specified index range

removeRange reference on Swifter

reverse

Reverses a CollectionType with an index conforming to BidirectionalIndexType

reverse reference on Swifter

sort

Sorts a mutable collection in place using the < operator or a user supplied comparison function.

sort reference on Swifter

sorted

Returns the Array obtained by sorting a SequenceType using the < operator or a user supplied comparison function.

sorted reference on Swifter

splice

Inserts the elements of a collection into a RangeReplaceableCollectionType at a given index.

splice reference on Swifter

split

split reference on Swifter

startsWith

Determines if the prefix of one SequenceType is equivalent to another SequenceType either using the == operator or a user defined equivalence function

startsWith reference on Swifter

stride

Creates sequences from a given value, to or through a given value, steping by a given increment (or stride).

stride reference on Swifter

underestimateCount

Will be covered in a future post.

Download the Playground

The playground for this, and all other posts in the series, can be found on GitHub in the SwiftStandardLibraryPlaygrounds repository.


Posted in Code Snippets, Swift, Swift Standard Library | Leave a comment