Get Your App Ready for iOS 9

Reading the tea leaves we probably have just about a month to make sure our apps are ready for iOS 9. I'm personally planning on being ready for the week of September 7 - 11.

You might have already invested some development effort in supporting larger more marketable iOS 9 features like universal links or multitasking on the iPad, but there are a few things you should have ready for iOS 9 launch regardless of how grand your plans for iOS 9 are.

San Francisco

Making sure your app looks like it belongs on the latest iOS is pretty painless this year. Apple is switching out the system font from Helvetica Neue to their new font San Francisco, originally designed for Apple Watch. Our apps will automatically start using the new font when running on iOS 9.

Or at least they should. I'm sure you never referenced Helvetica by name anywhere, right? Turns out I did accidentally. After noticing one label didn't look quite right in one of my apps I checked and realized I had set its font to Helvetica instead of the generic System. Oops.

Fortunately tracking down accidental references doesn't involve manually checking each UILabel in your Storyboard. Open your project and head over to the Find menu, then pick Find in Workspace. Type in "Helvetica" and hit enter. You'll get references to XIBs, code, Storyboards, and even any embedded HTML that references the font by name.

Find helvetica in your project

Anywhere you see the reference to Helvetica just switch to use "System" for your font instead. That'll make sure you're using Helvetica on an older OS and San Francisco on iOS 9 and later.

If you're trying to reference the system font in web views just prepend -apple-system[1] to your font-family list and it'll use SF in iOS 9 and Helvetica in older versions.

While you're in there take note: the font width is slightly different, so word-wrapping might change a bit and affect your layout. Best to play around with your app on iOS 9 for a few minutes and keep an eye out for any side-effects.

SafariViewController

If you've written an app that links to web content odds are you've gone through the trouble of building some kind of mini web browser in your app so users don't get booted out to Safari every time they tap a link. A single WKWebView or UIWebView by itself is never enough though and you'll usually need to go a bit further adding some basic history support, a progress indicator, "open in safari", etc.

This year Apple gave us SafariViewController (session 504) and it removes all that boilerplate code! Just give it a URL, present the controller, and you're done.

Not only are SafariViewControllers nicer for us developers, they're worlds better for the user. They support parental controls (which hopefully means the end of having to be rated 17+ just because you have an in-app browser), content blockers in iOS 9, cookies / shared logins, and more.

Fortunately you don't have to be iOS 9 only to use it. In fact Twitterrific already added support before iOS 9 is even out, and that trick is easy enough to do yourself.

Where you'd normally trigger your in-app browser go ahead and import SafariServices (checking if we're on iOS 9+) in your header:

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 90000
@import SafariServices;
#endif

Then, down where you'd normally open up your home-grown web browser, check to see if SafariViewController is available and use that instead:

- (void)showURL:(NSURL *)url
{    
    Class svcClass = NSClassFromString(@"SFSafariViewController");
    if (svcClass != nil) {
        id svc = [[svcClass alloc] initWithURL:self.urlToShow];
        [self presentViewController:svc animated:YES completion:nil];
    } else {
        //Your old web browser code here
    }
}

That's it! Adding SafariViewController support to your app is refreshingly trivial, no reason not to include it in your next update.

App Transport Security (ATS)

Security is hard, so hard that Apple is putting a system in place to help protect users from poorly configured or non-existent security by a developer. By default in iOS 9 if you try to load an HTTP resource in your app it's actually going to try to load the HTTPS version. If the HTTPS version is using security Apple considers weak, or the server just doesn't support HTTPS at all, the request will fail.

What does Apple expect out of our secure connections as of Fall 2015? [2]:

  • The protocol Transport Layer Security (TLS) must be at least version 1.2.
  • Connection ciphers are limited to those that provide forward secrecy (see the list of ciphers below.)
  • Certificates must use at least an SHA256 fingerprint with either a 2048 bit or greater RSA key, or a 256 bit or greater Elliptic-Curve (ECC) key.

To be fair this is what we should have been doing on our own all along: making sure our users' online activity is properly secured from unwanted network snooping. Many sites like Gmail and Facebook have already gone HTTPS-by-default on the web years ago and it's good for the user to have apps follow suit.

The easiest thing (yes, there's a good joke in there about SSL and "easy") to do is to make sure your server responds to HTTPS requests and is configured following recommended security practices. If you've done this already you don't have to do anything in-app.

If you need to buy yourself some time to implement these practices there are some good write-ups on which keys to add to your app's Info.plist to grant yourself exceptions to aspects of ATS temporarily.

Before you just go adding exceptions to your Info.plist and call it a day: it's important to have a plan to move your content to HTTPS, soon, even if the content is a read-only public resource. Fortunately the launch of Lets Encrypt is right around the corner which should make SSL'ing your content much easier, an perhaps most importantly, free.

My recommendation is plan to resolve any exception by the end of the year at the latest, when Lets Encrypt removes most of the excuses people have to not use SSL.

It's yet to be seen how hard Apple will come down us during app review in the coming years about ATS exceptions we request, but given their push on user privacy / security I'm planning to not need exceptions as soon as possible.

Swift Whole Module Optimization

Swift has already seen some great performance increases (both at run time and compile time) since 1.0 last year. Xcode 7 / Swift 2 adds a new optimization level for Swift that should yield some additional speed gains at run time. Apple covered a lot of great Swift speed tricks in session 409 but you get this one practically for free.

Before this option Swift files were optimized in isolation of each other, but with this new setting the compiler will check all Swift files in the module when deciding how it can optimize. It can now be a lot smarter about avoiding things like dynamic dispatch by viewing your project as a whole where classes and extensions might cross files.

If you have a project with Swift source code head into it's build settings and do a search for "optimization level". You'll see two results, you care about the one under "Swift Compiler". For your release configuration set the level to use the new whole module optimization flag.

Swift is already really fast at run time, but every little speed boost is nice, especially when it's free.

Low Power Mode

iOS 9 includes a new feature called low power mode. A user can enable it and expect to get about an extra hour of battery life throughout the day as iOS will disable background fetching, motion effects, lower the clock speeds on the GPU/CPU, and more.

It isn't just up to Apple to help users save battery life, our own apps can help pretty easily.

iOS will now send out a notification, NSProcessInfoPowerStateDidChangeNotification, when the system enters or leaves low power mode[3]. You can also query the current power state at any time by checking [[NSProcessInfo processInfo] isLowPowerModeEnabled].

If you have any points in your app where you might be able to save some power it's now a good idea to check the power state and respect the user's request to help save their battery. The biggest power savings would likely be in CPU-heavy tasks, complex animations, location updates, and network traffic (especially on cell networks) so take a quick look for areas in your code related to those to see if you might be able to take advantage of the flag.


  1. https://www.webkit.org/blog/3709/using-the-system-font-in-web-content/ ↩︎

  2. https://developer.apple.com/library/prerelease/ios/technotes/App-Transport-Security-Technote/index.html#//apple_ref/doc/uid/TP40016240 ↩︎

  3. https://developer.apple.com/library/prerelease/ios/documentation/Performance/Conceptual/EnergyGuide-iOS/LowPowerMode.html ↩︎