I recently released my new app, Chess Clock Plus, which I wrote entirely in Swift. This was my first all-Swift app. It was also my first iOS 8-only app, so it was a chance to explore the new APIs. In this post, I’ll discuss the new tricks I’ve discovered.
The Lesser-Known Gems of Swift
Swift is a new frontier with lots to discover. After using it for a few weeks, I still keep finding new features.
In Swift, having lots of optional properties can introduce some syntactic hassle. One common reason for making a property optional is to avoid instantiating it right away. Sometimes instantiating an object requires lots of time or memory. Ideally the value can start nil, and we lazily instantiate it when needed. Swift provides a lazy keyword that accomplishes this same behavior without the use of optionals:
This approach gives all the benefits of lazy initialization with less code, and therefore less bugs.
Hash and Underscore
Swift has some interesting operators that deal with parameter names. Let’s look at an example function:
Here we see that the function takes one argument. By default, Swift doesn’t need a parameter name for the first argument in a function, so we pass an unnamed integer.
To clarify the parameter, we can add a more verbose description:
We’ve added an external name to the first parameter, which forces the user of the API to include that name. This is where our first operator comes into play. In cases where you want the external and internal name to be identical, just use a # instead of writing the same name twice:
Here’s some clarification from Apple:
A hash symbol (#) before a parameter name indicates that the name should be used as both an external and a local parameter name. It has the same meaning as writing the local parameter name twice. The corresponding argument must have this name in function or method calls.
UPDATE: The # syntax is no longer valid in Swift versions >= 2.0
For all parameters other than the first, the # operator is implicitly included. This brings us to the second operator, which has the opposite effect. It potentially makes the parameters less clear, but allows for more concision.
An underscore (_) before a local parameter name gives that parameter no name to be used in function calls. The corresponding argument must have no name in function or method calls.
Here’s an example of a function whose name is very clear:
We could make this API more concise by using the underscore operator:
Swift allows us to specify default values for function parameters. This feature gives users of an API the choice to be concise or verbose. With other languages, creating this kind of flexibility can require lots of overloading, but with Swift it’s all condensed into one function.
Here’s an example of how to declare a function with an optional parameter:
Keep in mind that having parameter names is important with optional parameters; It’s easy to get the parameters confused if some of them are omitted. Although it’s not required, Apple recommends always putting optional parameters at the end of the parameter list:
Place parameters with default values at the end of a function’s parameter list. This ensures that all calls to the function use the same order for their non-default arguments, and makes it clear that the same function is being called in each case.
Access Level Modifiers
Many hurdles of learning a language involve finding new ways to express the things you could already do in previous languages. My favorite example so far is figuring out how to make a read-only property like in Objective-C. This is the equivalent idea in Swift:
This language feature is actually more granular than the readonly keyword in Objective-C, because you can set the access level to be private or internal.
No Key-Value Observing
There’s so many great things happening in Swift, which makes it all the more disappointing when something is missing. Key-Value Observing was one of the most useful features of Objective-C. Let’s hope it’s added in the future.
Useful iOS 8 APIs
iOS 8 has lots of new APIs, but I only ended up using a small portion them due to the small scope of Chess Clock Plus. Here are the ones that were useful for me.
This API lets you display multiple buttons when swiping a table cell. Although the iOS 7 Mail app had this feature, creating this effect in third-party apps required a more complicated workaround.
Here’s how I used it in Chess Clock Plus:
And here’s a code example:
My favorite part is the block-based API that lets you specify your button callback inline.
Speaking of blocks, UIAlertController adds long-awaited blocks APIs for UIAlertView and UIActionSheet. This new class is an instance of UIViewController, so you can present it in the normal way:
The only difference between presenting a UIAlertView vs. UIActionSheet is the preferredStyle argument. The rest of the API is exactly the same, so it’s easy to switch to the other type of alert, or to use different types depending on device size:
Lastly, there’s a useful new feature for UITableView. One of the worst parts of putting together a table before iOS 8 was sizing the table cells. Now you can use Auto Layout to do the work for you:
With these two lines, you can avoid implementing the heightForRowAtIndexPath function. UITableView will infer the height of the cell based on its content and constraints.
More to Discover
I’m sure there’s still more undiscovered features out there. As always, I look forward to continuing to learn as Swift and iOS grow.