Using teams in Apple Developer Center

How to manage your iOS development certificates and provisioning (the less painful way)

 


How to read this article

The purpose of this article is to bring awareness to the issue of provisioning profile management in iOS and how it can be mitigated using teams in Apple Developer Center.

If you’re reading this because you want to fix a provisioning related issue, and you don’t feel like reading anything more, feel free to skip the next few sections and head over to “Summary” directly.

If you’re reading this because you are curious about the topic, feel free to continue reading in sequence :).


 

The rant

Normally articles on Dev Monologue are quite cheerful. But this time their usual positive nature, will be substituted by a cold and dead serious theme. Provisioning profiles and certificates…

Oh my god... the horror... THE HORROR!!!!
-- anonymus Dev Monologue reader

The security aspect of the iOS developer program has always been a frustrating experiece, no doubt about that. Most people cannot seem to get their head around code signing. And what makes it even worse is that in every major Xcode release so far, many things get changed and at the end you never know what’s happening.

I’m going to take the liberty of even comparing it to git (and probably earn many people’s despise). Don’t get me wrong – I love git as much as the next guy. However, my observation is that most developers know a workflow of 6 or 7 commands in git that they use and everything beyond that is black magic. Go outside your comfort zone, and what follows is an endless stream of stack overflow threads and ultimately the shameful git clone all over again.

But now imagine that you write git clone only to find out that it doesn’t work anymore. Instead, there’s a “Fix ANY git problem EVAR” wizzard somewhere in Xcode that works as good as Windows’ network troubleshooting one.

I’m actually old enough to have developed for iOS at the times when Xcode had little to do with provisioning setup. You had to do all that manually. Generate a key pair, upload to the dev center, re-generate provisionings, add your devices manually… It was tedious, it was boring, it was confusing. However, once you actually understood what was going on, it got considerably easier to fix code signing related issues.

In contrast, nowadays many things are automated within Xcode. They don’t work… they are not well explained… but they are automated :O.
So problems either get fixed super easily.. or really, really hard. And I’m not really sure about the first because it has never happened to me (ok, ok, adding a device to the portal is much more convenient).

The example

My frustration with code signing reached its peak recently, when one of our provisionings expired. “It’s fine”, I thought, I’ll just renew it. And for the first time in my life I used the “Fix issue” alert in Xcode for its intended purpose. I revoked the old stuff and created a new one. To my surprise everything seemed to be working, which is already weird. A little investigation encovered that it only worked on my machine, everyone else couldn’t sign even after downloading the new provisioning.

Trying to use Xcode's Fix issue wizard

Long story short, I discovered that revoking certificates now also generates a new private/public key pair in your keychain, And ofc… that means the old one can no longer be used and unless you transfer it to all other machines, your teammates can take one rather long coffee break.

My initial thought was that this is horrific! It’s so error prone. And unless you take sick pleasure in reading release notes from Apple, you wouldn’t even know what’s happening. And knowing (unfortunately) many developers, suddenly private keys, using a passphrases like “1234” start flying around in Skype, Slack, email and.. I don’t know… maybe even Facebook.

After my anger settled down, I decided that there must be a better way. I instinctively thought about teams. I knew the dev center supported multiple users, but to be honest, I had never been in a team that used them. So what are they all about?

Teams in Apple Developer Center

The intention is that every person in your team participates in the dev account with his own AppleID. There are three tiers of permissions – team agent, admin and a member. Intuitively, the agent can renew memberships and work with payments and legal documents, a member can work with developement certificates and an admin can work with both development and distribution. You can learn more about team roles in the developer reference.

But the point is different. In that scheme, you generate provisionings on a team basis. This provisioning can be used with several certificates – one for each member of your team.

This is very powerful because now each developer is responsible for his credentials and certificates. Also you don’t have to share private keys with others. Apart from an excellent security practice, this makes it very convenient to work with freelancers (because ofc they shouldn’t have access to company private keys).

And that being said, those new changes in Xcode start making sense. Yes, if you go to Xcode -> Preferences -> Accounts -> View Details, with only one mouse click, you can revoke a certificate and regenerate a private/public key pair, but you’re only doing it for your personal account. Everyone else can continue working undisturbed.

It’s so simple… and obvious… and yet I’m scared to know how many companies don’t levarage teams in Apple Developer Center. Suddenly privisioning setup is a breeze (relatively… and considering the alternative). For detailed steps how to achieve that, please refer to Maintaining Your Signing Identities and Certificates.

Summary

Initially, it might be tempting to use only one iOS developer account across your whole team for provisioning. However, with changes to Xcode and the member center, it is becoming increasingly difficult to do so without encountering code signing issues from time to time. Namely, nowadays it’s way too easy to revoke a certificate from within Xcode, leaving the old private/public key pair invalid. This in turn prevents other team members from being able to run applications on your test devices.

Introducing teams in Apple Developer Center can help prevent that by having each programmer sign apps with a different certificate, all connected to the same provisioning. Even if someone revokes a certificate, he only does so for his own account – everyone else’s workflow remains undisturbed. This brings higher level of security and better organisation within the team. Also, since this is the intended way, you get easier and better support from Xcode. You can turn a mammoth task such as provisioning, into a stramlined process.

To get started with teams in Apple Developer Center, go ahead and read the following developer reference document. For more information on permission tiers, refer to team roles in the developer reference.

Text Kit exclusion paths

Normally, a good author would wait until the end to reveal his ultimate thoughts on a subject, but since I’m probably not a good author, I’ll allow myself to skip right to it:

What a time to be alive…!

That was my reaction when I first read about Text Kit exclusion paths. Seriously speaking,
I was generally impressed at the little gems that are now available within the Cocoa framework. Anyway, before I get too emotional, lets get started:

What is Text Kit

Text Kit is a framework, introduced in iOS 7, that brings some advancements in text rendering for iOS projects.
To explain why this is so exciding, I’ll have to take you back to the old days of iOS development.

Prior to iOS 6, while most UI components would provide a fair amount of text visiolization customizations, they were all limited to fonts, colors and alignments.
Even simple things like bolding a single word in a label was unavailable.

Try explaining that to your designer…

Naturally, this is a weird limitation since it’s such a basic requirement. It’s everywhere, so it’s a bit difficult to convince people why this would be more difficult than they expect.

To be fair, it’s not just iOS. Most platforms are not much better. If you want to perform even the most basic text formating operations, you have to go for HTML.

And that’s exactly what happened in iOS 6. Suddently, “rich-text” formating was made nice and easy. But looking under the hood, one would quickly realize that what powers that new functionality is actually something you should be familiar with, namely WebKit. So in reality, that was no better than using HTML.

To be honest, a little HTML processing has never hurt anyone (actually, it probably has), and I’m pretty sure there wouldn’t be any performance considerations unless you really go overboard with it. However, there’s something inside me that cringes everytime I hear about using HTML in a native app.

Luckily, this is no longer an issue. Because with the “invention” of iOS7, Text Kit has got your back.

What Text Kit can do for you

Text Kit will not pay the rent when it is due, unfortunately, but it will make you not have a panic attack everytime you have to visualize text in anything but the most trivial way.

If you go to the reference page for Text Kit you’ll find all kinds of low level text and font… thingies like glyphs. As a man who can hardly distinguish between fonts, I wouldn’t want to go into details about this, though. I’ll just stick to the other aspects of Text Kit.

Changing text layout

So, what even I can find useful in a framework such as Text Kit, is its ability to get you involved into the way text is being laid out on screen.

A certain limitation I’ve stumbled upon several times in my career, is that all text containers in the Cocoa framework (and most others), are constrainted to a rectangular shape. I don’t really blame the architects, since that covers 99% percent of the cases. But what if you wanted to have text floating around an image like in a magazine? Pretty cool, eh? WELL, YOU CAN’T HAVE IT!

Why? Well, you’re faced with the following problem…
All UI components that display text have a rectangular shape. And also, they don’t expose that much functionality to allow you to affect the way text is being layed out. Now that’s tough… You’ll either have to ditch your floating text idea, or go for Core Text or something. And suddenly, you’re working weekends, you let yourself go and you realize you no longer have any friends (provided that you had any before).

I might have over-exaggerated that last part, but you get the point. It’s useful to add additional constraints on the test layout.

Text Kit exclusion paths

Text Kit exclusion paths to the rescue!
Here’s the statement you’ve all been waiting for while I keep writing nonsense:

Text Kit exclusion paths allow you add additional rules affecting how text is rendered inside a text view. Using them, you can specify locations within the container where text shouldn’t be drawn. This effectively means that achieving a “magazine-like” UI, where text floats around images, becomes rather easy. You just add the frames of your image views as exclusion paths and (hoprefully) your wishes come true.

Without further adu… some code:

UIBezierPath* path = [UIBezierPath bezierPathWithRoundedRect:self.imageView.frame
byRoundingCorners:UIRectCornerAllCorners
cornerRadii:CGSizeMake(15, 15)];
self.textView.textContainer.exclusionPaths = @[path];

Only two lines of code… iOS development is getting lazy. So first of all, exclusion paths are always bezier paths.
I realize some of you are ready to close the tab, but in this case… SHAME ON YOU. It’s not that bad. Also, the UIBezierPath class has a lot of simple constructors specially tailored to those, unfamiliar with graphics.

In our case, we don’t really need a complex curve, so we can just get away with creating a bezier curve based on a rectangular. And we will also include a corner radius to make the text frame more interesting.

Once that done, we set the exclusionPaths property with an array containing all curves we created. Really simple…

Text Kit rectangular for text

Maybe I’m being cheeky, but I’m wondering if Text Kit can do more. What’s another text related problem Cocoa is notorious for NOT solving.
OH, got one! And I’m sure you’ve also encountered it.

How much screen space will a text view need to draw a certain amount of text?

I don’t know about you, but I’ve had a lot of sleepeless night because of this. Sure, Autolayout resolves this problem most of the time, but not always.
Also there’s this method:

[myLabel.text sizeWithFont:[UIFont systemFontOfSize:14]]; // depricated btw

But last time I chacked it didn’t work very well for multiline labels.
So it is possible… no, I doubt it. But maybe… just maybe… it works with Text Kit…?

CGRect usedRect = [self.textView.layoutManager usedRectForTextContainer:self.textView.textContainer];

IMPOSSIBRU! As I said in the beginning… What a time to be alive!

Text Kit NSTextContainer and NSLayoutManager

Now that you’re totally impressed by the Text Kit exclusion paths, lets get to the boring part. What were those objects we used in the previous examples, namely layoutManager and textContainer. As seen on the reference page for Text Kit, the architecture for the Text Kit framework is as follows:

Text Kit classes

Basically there are three classes to consider:
* NSTextContainer
* NSLayoutManager
* NSTextStorage

NSTextContainer

Represents a region on screen where text should be drawn. And as we saw previously, contains exclusion paths for areas on screen that should not have text.

NSLayoutManager

NSLayoutManager is responsible for converting the text you provide into a series of letters (glyphs within the context of Text Kit) drawn on screen

NSTextStorage

NSTextStorage might sound fancy, but it’s actualy the string object that stores the text you want displayed.

Feel free to go ahead and read about each of these classes and discover all goodies Text Kit can offer.

AVAudioSession bluetooth support

Bluetooth's logo

Adding Bluetooth audio support to an iOS app

If you’ve come here via an internet search, I assume you’re already pulling your hair out trying to add bluetooth support to your app. I can almost feel your pain. I’ve been through it all. I will give you a few pointers about implementing  AVAudioSession bluetooth support, but keep in mind that I’m no expert. I don’t, by any means, feel like I know much about iOS audio. I just had the fortune to successfully get AVAudioSession bluetooth working and decided to share my knowledge with the hope that some day I might be able to help someone though tough times. So bear with me :)

AVAudioSession bluetooth support source code

Adding AVAudioSession bluetooth support actually takes a lot less code than you might think. In fact, the whole audio sessions API is so simplistic that everything happens either very easy or incredibly hard. Guess which category AVAudioSession bluetooth support falls in?

Adding bluetooth to an AVAudioSession involves several features as far as I’m concerned. Lets go through them all:

Enabling bluetooth audio

First of all, you need to specifically instruct AVAudioSession that you allow sound to be routed to bluetooth devices. This can be done while setting your audio category:

[session setCategory:AVAudioSessionCategoryPlayAndRecord 
         withOptions:AVAudioSessionCategoryOptionAllowBluetooth
               error:&error];

Remember, your audio session category tells iOS how you plan on using sound within your app. For instance, AVAudioSessionCategoryPlayAndRecord means that you want to both play and record audio. Anyway, what we are interested in, is the options parameter. By adding AVAudioSessionCategoryOptionAllowBluetooth, we allow iOS to play our app’s audio on a bluetooth audio device.

Note: I’ve seen projects where a category is set on an AVAudioSession in multiple places. If I’ve learned anything about audio in iOS is that you don’t use setCategory: lightly! In fact, in most cases you should only set is once. Why? For one thing it is a complex operation. If it’s executed on the main thread, it will make your UI unresponsive for a second. But more importantly, setting the category all over the place might lead into strange behavior – you will never know when audio will be going to the speaker or the earphone…

Switching between audio routes

When you are implementing AVAudioSession bluetooth support, you will probably want to be able to switch between audio devices. And there doesn’t seem to be a clearly defined way to do that in the documentation.

There are several ways to do it. However, what I found to be the best working one is setting the preferred audio input. Here are some examples:

Switching to bluetooth

- (AVAudioSessionPortDescription*)bluetoothAudioDevice
{
    NSArray* bluetoothRoutes = @[AVAudioSessionPortBluetoothA2DP, AVAudioSessionPortBluetoothLE, AVAudioSessionPortBluetoothHFP];
    return [self audioDeviceFromTypes:bluetoothRoutes];
}

- (AVAudioSessionPortDescription*)builtinAudioDevice
{
    NSArray* builtinRoutes = @[AVAudioSessionPortBuiltInMic];
    return [self audioDeviceFromTypes:builtinRoutes];
}

- (AVAudioSessionPortDescription*)speakerAudioDevice
{
    NSArray* builtinRoutes = @[AVAudioSessionPortBuiltInSpeaker];
    return [self audioDeviceFromTypes:builtinRoutes];
}

- (AVAudioSessionPortDescription*)audioDeviceFromTypes:(NSArray*)types
{
    NSArray* routes = [[AVAudioSession sharedInstance] availableInputs];
    for (AVAudioSessionPortDescription* route in routes)
    {
        if ([types containsObject:route.portType])
        {
            return route;
        }
    }
    return nil;
}

- (BOOL)switchBluetooth:(BOOL)onOrOff
{
    NSError* audioError = nil;
    BOOL changeResult = NO;
    if (onOrOff == YES)
    {
        AVAudioSessionPortDescription* _bluetoothPort = [self bluetoothAudioDevice];
        changeResult = [[AVAudioSession sharedInstance] setPreferredInput:_bluetoothPort
                                                     error:&audioError];
    }
    else
    {
        AVAudioSessionPortDescription* builtinPort = [self builtinAudioDevice];
        changeResult = [[AVAudioSession sharedInstance] setPreferredInput:builtinPort
                                                     error:&audioError];
    }
    return changeResult;
}

Wow, that was a lot of code! Well, the important bit is setting the preferred input in the last method. The other code is just to get the right AVAudioSessionPortDescription object for speaker, earphone or bluetooth.

Switching to speaker

While there are other way to do that, this is what I prefer to use:

- (BOOL)switchSpeaker:(BOOL)onOrOff
{
    NSError* audioError = nil;
    BOOL changeResult = NO;
    if (onOrOff == YES)
    {
        changeResult = [[AVAudioSession sharedInstance] overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker
                                                           error:&audioError];
    }
    else
    {
        AVAudioSessionPortDescription* builtinPort = [self builtinAudioDevice];
        changeResult = [[AVAudioSession sharedInstance] setPreferredInput:builtinPort
                                                                    error:&audioError];
    }
    return changeResult;
}

Switching to earpiece

This one is easy. It’s just the opposite of switching to speaker:

- (BOOL)switchEarphone:(BOOL)onOrOff
{
    return [self switchSpeaker:!onOrOff];
}

AVAudioSession bluetooth support can be a daunting task. And there isn't much information about it in the internet. I hope this article helps you with your task. Thanks for reading!

WatchKit tutorial

WatchKit logo

Do you even iWatch, bruh?

Sorry, I just had to write that. Anyway, we developers have to stay up to date with new technologies. And which is the newest gadget out there in the iOS scene (no, it’s not beacons). It’s the iWatch. I, personally, wouldn’t buy it any time soon (or any kind of smart watch for that matter). I’m doing just fine with my Citizen “dumb” watch, thank you. But that doesn’t mean the iWatch doesn’t interest me in a professional point of view. And since Apple recently published some developer resources about it, I thought I should write this WatchKit tutorial.

The WatchKit

So I watched the video… I read the developer guide… and I must say, I’m not that impressed. Guess I’m a romantic when it comes to new tech. Truth is, the iWatch is so tightly coupled with your iPhone that it barely serves any purpose at all, apart from displaying notifications. Even in the iOS simulator, it is listed next to the External monitor settings :).

iWatch in the iOS simulator

But all things considered, a smart watch is just a way to see some information without getting your phone out of your pocket so I really can’t complain.

All that can be clearly seen by looking at the WatchKit framework. Almost everything is run by your iPhone, leaving only a Storyboard to the watch. Even IBActions are handled on the phone.

WatchKit architecture

From the diagram above, you can see that an iWatch app goes nowhere without it’s big brother, the WatchKit extension. It only presents a predefined storyboard while the iPhone handles all “heavy-lifting”. And when I say “predefined” I mean that you cannot even dynamically create UI elements. The best you can do is put all elements in the storyboard and have some of them hidden. Not good…

Anyway, since this is a WatchKit tutorial, I’ll stop with the whining.

The WatchKit tutorial

Right, first of all, a WatchKit tutorial should start with installing and enabling iWatch developement.

Install Xcode 6.2 beta

After a while, WatchKit will be available in Xcode’s stable version and most of the people reading this will not need to go through that step but for now, you need to download and install the latest Xcode beta. You can check what version of the IDE you are running and if it is 6.2 or above, you should be all set.

All the rest of you, head over to Apple’s developer portal and download the latest beta. For those who do not participate in Apple’s iOS developement program, I’ll have to stop you right there. You will no have access to beta versions. Sorry guys… maybe after iOS 8.2 comes out. To summarize:

Note: You will not be able to download Xcode beta without participating in Apple’s iOS development program.

Getting started with the WatchKit tutorial

After installing Xcode 6.2, the first thing I did was try to create a new project, using iWatches. But, there was no such thing…
As discussed above, WatchKit involves running code on the phone. You can only add WatchKit support to existing projects. So, to get started with this WatchKit tutorial,
go to “Add Target” and select “Apple watch”. This will setup everything you need in order to start using WatchKit for this project. You can also do it manually, but since it creates new targets and storyboards, it is easier to just use the wizard.

New terminology

While reading about WatchKit, you will probably hear a few terms that you are unfamiliar with. Lets see what they are:

Glances

The idea behind Glances is actually quite simple. The iWatch is designed so that users can quickly access information about the apps in their phones. This is achieved by allowing each app to have a single, nonscrollable screen that summarizes the current state an application is in. This special view, or more specifically scene in your storyboard, is called a Glance. It’s important to note that Glances are non-interactive and they shouldn’t contain controls, such as buttons and sliders. If a user taps on a Glance, the corresponding Watch app is launched.

Custom Notification interfaces

Custom notification interfaces

In the (quite recent) past, local and remote notifications were static and managed by iOS. When iOS 8 came along, they became interactive. For the first time, developers were able to do some minor customization on what their notifications did. WatchKit takes this even further by allowing apps to provide custom appearance and functionality to the notifications displayed on the iWatch. They still cannot be very interactive, but they can look different than the generic ones. Tapping on a custom notification results in launching your Watch app, so using buttons and other interactive controls is unavailable. There are two kinds of notifications interfaces:

Static notification interfaces

The static notification interface is a simplified version of your notification appearance. It can only contain static images and text. In fact, the only item that changes is the notification text. This is done by connecting the notificationAlertLabel outlet to a WatchKit label.
The idea behind this is that if the iWatch fails to initialize your “real” notification in time, it will display this static one. I’m not sure how often this will be, but either way, you are required to support that.

Dynamic notification interfaces

Dynamic notification interfaces is what we were waiting for. It allows you to specify a custom “view controller” to display the notification. And when I say “view controller”, I don’t mean UIViewController unfortunately. It’s WKUserNotificationInterfaceController, a WKInterfaceController subclass – UIViewController’s crippled brother. In fact, WatchKit doesn’t use UIControls anywhere. It has it’s own (rather sad) UI elements. But more on that later.

Dynamic notifications in WatchKit are not interactive (apart from the action buttons that you can add). They should be designed to only display information. Tapping on the notification will result in opening the Watch app.

In your WKUserNotificationInterfaceController subclass, you will rely on the following methods in order to handle incoming notificaitons:

Swift

func didReceiveRemoteNotification(_ remoteNotification: [NSObject : AnyObject]!, withCompletion completionHandler: ((WKUserNotificationInterfaceType) -> Void)!)

func didReceiveLocalNotification(_ localNotification: UILocalNotification!, withCompletion completionHandler: ((WKUserNotificationInterfaceType) -> Void)!)

Objective-C

- (void)didReceiveRemoteNotification:(NSDictionary *)remoteNotification
                  withCompletion:(void (^)(WKUserNotificationInterfaceType interface))completionHandler

- (void)didReceiveLocalNotification:(UILocalNotification *)localNotification
                 withCompletion:(void (^)(WKUserNotificationInterfaceType interface))completionHandler 

Glances and notifications in the storyboard

Everything in an iWatch app is done via the Storyboard. Everything! So how do you add your glance and notifications controllers in there. Well, every storyboard has an entry point right? WatchKit introduces three new ones. A typical Storyboard for a Watch app, contains a Main, a Glance and a Notification entry point. If you go through the “Add new Apple Watch target” wizard, these are already setup for you, apart from the Glance. To add the latter manually, just add a new “Glance interface controller” to the scene and Xcode creates it for you.

WatchKit tutorial – the framework

Let’s finally talk about the classes in the WatchKit framework. Truth is, there aren’t that many. I was a bit disappointed. A whole new devices is just managed by a handful of classes. The main ones are:

WKInterfaceController

WKInterfaceController in WatchKit is the same as UIViewController in UIKit. I’m a little disappointed that we cannot use our standard Cocoa classes, though.
Anyway, WKInterfaceController is a lot more restricted and has a different life cycle. Instead of methods like viewDidLoad, loadView and ViewWillAppear, there are:

initWithContext:

This is the designated initializer for WKInterfaceController. The context parameter is used in order to pass any data from a previous interface controller to this one. Is it just me or there is a little influence from Android here?

willActivate and didDeactivate

These are the methods you’d override in order to get notified whenever an interface controller becomes visible or is being dismissed. willActivate is the place you will need to make sure your controller’s information is up to date and you can use didDeactivate in order to clean up.

WKUserNotificationInterfaceController

WKUserNotificationInterfaceController is a WKInterfaceController subclass that is used to display custom notification interfaces (more information about that above).

WKInterfaceDevice

This class contains same basic information related to the iWatch. This includes screen bounds, scale and current locale. You can also use it to manage your images cache. WatchKit allows you to store up to 20 MB of cached images on the iWatch itself in order to reduce latency time whenever they are needed. Remember that the iPhone and iWatch communicate via bluetooth – transferring images can take a while.

WKInterfaceObject

This is the base class for all UI controls supported by WatchKit. As I said, you cannot use UI views from UIKit. All you can do is use the ones that WatchKit provices for you. These are:

  • WKInterfaceButton
  • WKInterfaceDate
  • WKInterfaceGroup
  • WKInterfaceImage
  • WKInterfaceLabel
  • WKInterfaceMap
  • WKInterfaceSeparator
  • WKInterfaceSlider
  • WKInterfaceSwitch
  • WKInterfaceTable
  • WKInterfaceTimer

WatchKit layout

WatchKit does not use Autolayout to position it’s element. This is a bit weird, bit I guess it was too complex for the slow iWatch. So Apple came up with a layout system that positions elements relative to each other in a horizontal or vertical order.

LinearLayout! Again, some Android deja-vu…

All this is controlled in Interface builder via the Attributes inspector. And for something this simplistic, it works rather well.

Attributes inspector

WatchKit tutorial – the code

Finally, the code!. I’ve created a sample project where you can see how everything is setup for WatchKit developement. It doesn’t do much, but it should be enough to get you started with WatchKit. You can download it here. Here it is in action:

WatchKit tutorial sumulator run

If this WatchKit turorial was enough to get you excited about iWatch developement, you can to Apple’s WatchKit programming guide and learn more.

Swift Closures

This post is part of a Swift vs Objective-C series where we look at new features in Swift and how they compare to their predecesors from Objective-C. In this article, we are going to discuss Swift closures.

What are Swift closures?

Depends who’s asking…
To an Objective-C developer, a closure is Swift’s equivilent of blocks.
A formal definition should be that Swift closures are self-contained blocks of functionality
Intuitively, a closure is a kind of anonymous, nested functions. It’s a chunk of functionality that you can pass around in functions and variables.

In reality, closures and blocks do little more than provide a more convinient way of encapsulating functionality than nested fuctions and function pointers. Despite that, in the past couple of years, there has been a massive effort to integrate blocks into our Objective-C code.

Swift closures synthax

Swift closures closely resemble Objective-C (or any other language, supporting them) blocks. To define one, you’d write something like this:

{ (parameters) -> return_type in
    // block body
    // write code here
}

This is longest, most formal way of creating Swift closures. As with all languages influenced by functional programming, there are many shorter versions, which we will cover shortly.

Closures as function parameters

Let’s face it, you are most likely to use Swift closures as parameters. Let’s take a look at some specifics to doing that.
First of all, it is important to know how to define a function that takes swift closures as one of it’s parameters:

func calculateSomething(something1:Float, something2:Float, calculator:(value1:Float, value2:Float) ->Float) ->Float {
    return calculator(value1: something1, value2: something2)
}

I hope there is nothing disturbing in this statement to you. It’s a function that takes three parameters – two floating point numbers and another one called calculator. When we inspect it’s type, we will discover that it’s not a basic data type or a class. It’s a function signature, specifying what parameters the closure takes and what value it returns.

Now, to use the calculateSomething function, we can do the following:

calculateSomething(23.76, 125, {(value1:Float, value2:Float)->Float in 
    return value1 + value2
})

Written like this, the function is calculating sums. As you can see, we supplied two numbers and a closure that is essentially a very complicated + operator. However, as with most “functional” languages, that is simply too long to write. Life is too short to write swift closures with the full synthax. That’s why there are shorter versions of this statement.

calculateSomething(23.76, 125, {(value1:Float, value2:Float) in 
    return value1 + value2
})

Type inference to the rescue! Since the compiler already knows the signature needed for this function call, it can “guess” what a suitable closure would look like. That’s why we can skip explicitly specifying it’s return type. You might wonder if the same is true about the parameter’s type. Well, it is…

calculateSomething(23.76, 125, {(value1, value2) in 
    return value1 + value2
})

All data types can be inferred from the function definition.
While we are at it, we can also omit the parenthesis:

calculateSomething(23.76, 125, {value1, value2 in 
    return value1 + value2
})

Next, we can continue with the closure’s body. In swift, you can omit the return keyword for functions that have only one statement. Since this is the case in our example, we can shorten our code even more:

calculateSomething(23.76, 125, {value1, value2 in 
    value1 + value2
})

But wait, there’s more! Here’s an interesting little feature from scripting languages. You might know (from Bash for instance) that you can access function and script paramenters using the $ synthax (like $0, $5, $8). So…

calculateSomething(23.76, 125, {
    $0 + $1
})

Note that inlike Bash, where $0 is the path to the script being executed, in Swift it is actually the first parameter.

Pretty nice, eh? Our function call got a lot shorter. Of cource, this is just synthax sugar. It doesn’t add any expressive power to swift closures – it just makes them more convenient to write and read.

As a bonus for being so patient, here’s one final short form. Since the closure we were using sums two numbers, which is exactly what + does… we might as well use that operator:

calculateSomething(5.0, 12.6, +)

Yes, that’s a thing in Swift.

Variables of type closure

Sometimes, it can prove useful to store swift closures in a variable. So, let’s briefly talk about that.

let closureVar = {(value1:Float, value2:Float)->Float in 
    return value1 + value2
}

By now, you should be comfortable with this synthax. It’s not much different than what we looked at above. Though, it looks like a long this to write. It almost makes you not want to use that variable. Can’t we use something shorter, like we did last time?

let closureVar2 = {(value1, value2) in 
    return value1 + value2
}

It doesn’t work ;(. Why? Well, we can omit the parameter data types and return value only if the compiler can infer them from the context. And since we didn’t specify the closureVar2‘s type, Swift doesn’t know the closure’s signature that it should expect.

let closureVar3:(value1:Float, value2:Float) ->Float = {(value1, value2) in 
    return value1 + value2
}

Explicitly adding a type to our variable solves that problem, but our statement is no longer that short.

Now that we have a variable containing our closure, we can use it in all situations a closure is needed. Like in all examples from the previous paragraph:

calculateSomething(5.0, 12.6, closureVar)

Capturing values

This section contains some general information about capturing values. If you are familiar this concept from Objective-C’s blocks, feel free to skip the following paragraph.

Everything up until now is not that impressive to be honest. Being able to store functions in a variable and use them as parameters is a standard feature of most languages. What makes Swift closures (also blocks and lambda functions in Objective-C and other languages) so popular, is capturing values. The concept is rather simple. Unlike conventional function that operate in a sort of a vaccum, closures have the ability to use variables defined in the code block enclosing them. Let look at an example:

func myFunction() {
    var funcVariable = 15
    let closureVar: () = {() -> () in
        // This closure will be able to access variables 
        // from the function it was defined from -
        // funcVariable for instance
        var closureVariable = funcVariable
        funcVariable = 25
        }()
    closureVar
    print(funcVariable)
    // funcVariable is now 25
}

The outer function myFunction creates a local variable funcVariable. After that it defines a closure, which is able to use that local variable and even change it. Actually it has a reference to it so that if the value is modified within the closure, the new value doesn’t get lost as soon as the code block ends.

Retain cycles with Swift closures

Capturing values is a pretty useful feature. However, there are some things to be careful with. As the title suggests, they are related to retain cycles. Since the closure has to make sure all local variables that it needs from it’s container are readily available within it’s body, it retains them. It is possible that an object retains a closure, and that same object is used within the closure’s body, meaning that they both keep each other “alive”. Most often this happens when a class has a closure as a member variable and that same closure uses self within it’s body. In such cases, the object retains the closure, which in turn retains the object of the class.

Retain cycles like these are relatively hard to track because they are very subtle. And with ARC, things are getting even worse as most developers lose the habbit of thinking about memory management.