Mobile
Article
By Jordan Morgan

A Developer’s Introduction to iOS 9

By Jordan Morgan

Every year at WWDC, Apple unveils a new version of iOS. Ever since the announcement of iOS 2, Cocoa Touch developers know it’s a time to study documentation, view sample code, and ready their code for the new APIs.

This year with iOS 9, Apple has added many useful features and refined existing ones. While it wasn’t a ground-breaking change like iOS 7, there is a lot of new functionality to learn.

In this article, I will discuss some of my favorite changes and additions in iOS 9.

UIKit

UIKit is used in every iOS application and drives user interfaces. With iOS 9, Apple has fundamentally changed the way developers should approach creating layouts with the new UIStackView.

UIStackView

The new stack view is so important that Apple has recommended that you should begin building your user interface using stack views and only deviate when interfaces become too complex or highly customized. The stack view abstracts a lot of the work of creating constraints away from the developer. You insert items into the stack view, and UIKit assigns the proper constraints automatically at runtime.

There are several ways to work with the stack view within interface builder. You can select a horizontal or vertical stack view from the object library or use the dedicated button towards the bottom of Xcode:

Stack View

Using these in code is easy. To take advantage of the stack view, you need to specify three key things:

  • Which axis the stack view is on
  • How it should arrange the subviews
  • How those subviews should be distributed

One thing that may be initially confusing is how to remove a stack view from the view hierarchy. This is a two step process. You need to remove the subview from the stack view’s arrangeSubviews property and also call removeFromSuperview(_:) from the subview instance. The whole process might look like this:

//Init stack view
let horizontalSV = UIStackView()
horizontalSV.axis = .Horizontal
horizontalSV.alignment = .Center
horizontalSV.distribution = .Fill
self.view.addSubview(horizontalSV)

//Add a view
let aView = UIView()

//Add subviews
horizontalSV.addArrangedSubview(aView)

//Removing
horizontalSV.removeArrangedSubview(aView)

//Take out of view hierarchy
aView.removeFromSuperview()

UIKit Dynamics

The always popular, and playful, UIKitDynamics API has a new behavior. In addition to now supporting nonrectangular collision bounds (i.e. paths), there is a new behavior class for new attachment types for UIAttachmentBehavior.

The new behavior, UIFieldBehavior, allows developers to model vector force fields. Apple has even provided a nice code sample to demonstrate how to use it here. It’s worth downloading to see the new behavior in action and view the code samples showing how to implement it.

UICollectionView Enhancements

Collection views have become the favored approach to showing lists of data in Cocoa Touch since introduced in iOS 6. They have distinct advantages over table views, but the biggest is being able to define a custom layout.

In iOS 9, they’ve grown even more powerful and intuitive. The new boolean property, sectionHeadersPinToVisibleBounds, forces the flow layout to work much like a table view always has. Section headers will now stick to the top of the screen during scrolling.

They can also be easily reordered. If you are using a UICollectionViewController, set installsStandardGestureForInteractiveMoment to true. With one line, users now have the ability to order items however they wish within their user interface.

UIPickerView Enhancements

Developers all over the world have written hacks to size picker views correctly. Now picker view has native support for resizing and adaptivity. In the previous versions of iOS, both the date picker and picker view would enforce a default size even if you attempted to manipulate them. The default width of both controls is now 320 points. Previously, it would be the device width of the iPhone presented on.

Few have mentioned the recently added function activateConstraints(_:) on NSLayoutConstraint. This was added in iOS 8, and activates a set of constraints with one call.

The Contacts API

For too long developers have had to rely on an API built on C to use contact information in their apps. Finally, Apple has given us a full object oriented API via two new frameworks: Contacts and ContactsUI. These replace both the Address Book and Address Book UI frameworks.

Using the new API is much less painful than the old approach:

import Contacts

//Create the contact with a name
let contact = CNMutableContact()
contact.givenName = "Jordan"
contact.familyName = "Morgan"

//Setup other info
let homeEmail = CNLabeledValue(label:CNLabelHome, value:"jordan@morgans.com")
let workEmail = CNLabeledValue(label:CNLabelWork, value:"jordan@dreaminginbinary.com")
contact.emailAddresses = [homeEmail, workEmail]

//Address
let homeAddress = CNMutablePostalAddress()
homeAddress.street = "1 Somewhere Lane"
homeAddress.city = "Springfield"
homeAddress.state = "MO"
homeAddress.postalCode = "65807"
contact.postalAddresses = [CNLabeledValue(label:CNLabelHome, value:homeAddress)]

let birthday = NSDateComponents()
birthday.day = 6
birthday.month = 10
birthday.year = 1988  //You can leave the year off if you want
contact.birthday = birthday

//And just save it!
let store = CNContactStore()
let saveRequest = CNSaveRequest()
saveRequest.addContact(contact, toContainerWithIdentifier:nil)
store.executeSaveRequest(saveRequest)

Multitasking

For users, this will be one of the best forward facing enhancements, although its not available on all devices at present. The best part (or worst depending on one’s code base), is that an app might work almost out of the box with this feature. Take Twitter, for example:

Multitasking App

This can be supported by using the iOS AutoLayout and Size Classes. If the code base already uses these extensively, then there’s not much to do.

Essentially, iOS will be manipulating Size Classes at runtime when the user drags their finger to setup multitasking. If the screen is split in two and each app takes up a half of the screen, they both might be of regular width and height. If one app takes up two thirds of the screen and the app developer’s only takes up a quarter (as in the picture above), it’ll be in compact width and regular height. It’s time to stop avoiding AutoLayout and Size Classes!

Apple announced that they wanted iOS 9 to be more intelligent and respond to the way you use your device. Siri will now make better guesses as to what data a user is trying to access, what the user’s routine looks like and more. This will allow developers to deep link from Search in iOS 9.

Using the Search API, developers can let users supply relevant information to navigate directly to. In the picture below, the user searched for Maui and the popular traveling app, Kayak, brought up a flight from the user’s current location to Maui:

Context Search

Though I couldn’t find the source to this quote, I’ve read that users spend a staggering 86% of their time in apps when using iOS. It’s important we make it as easy as possible for users to end up inside our own apps.

With search, you can achieve this by exposing information about your app with three primary APIs:

  • NSUserActivity: Previously viewed app content.
  • Web Markup: App content which is also supported on the web.
  • CoreSpotlight: This will probably be the most common method, any part of an app can be exposed using this API.

CloudKit JS

Who would have thought that one of the biggest announcements at WWDC would involve javascript? CloudKit now boasts a rich javascript API, which is important because most “connected” apps typically require some sort of web presence. CloudKit JS provides a web interface to work in unison with the iOS app.

CloudKit JS will access the same containers as its iOS counterpart. This means all of the data can flow freely from the two devices. Apple has exposed the framework from its own CDN if developers don’t want to host it themselves:

<script src="https://cdn.apple-cloudkit.com/ck/1/cloudkit.js">

From there, enable web services for the app’s container from the CloudKit Dashboard. The API is built using a RESTFUL architecture and data can be retrieve and POSTed via JSON. For example, the endpoint for modifying an existing record looks like this:

POST [path]/database/[version]/[container]/[environment]/[database]/records/modify

As CloudKit’s pricing is competitive, this may be the missing link that helps it compete with similar services like Parse.

App Thinning

This is a big win for developers. One of the worst things that can happen to us as developers is to miss out on sales because the user wasn’t connected to WIFI to download our app. Now, Apple is helping eliminate these types of problems using a concept they are calling “App Thinning”.

With App Thinning, users will only download parts of the binary that are relevant to the user. For instance, if the user has an iPhone 6+, the download won’t download the @1x or @2x images since they will not be used and only download the @3x images.

App Thinning has three main components:

  • App Slicing: This is the process of only downloading what’s needed.
  • On Demand Resources (ODR): Resources hosted by the App Store that can accessed after the user has downloaded the app. For instance, new levels in a game via in app purchase.
  • Bitcode: Allows Apple to re-optimize the app’s binary in the future without having to submit a new version.

Perhaps the best part about App Thinning is that two of it’s components are practically done, App Slicing and Bitcode. I personally think it’s a fantastic idea, as developers have been doing this independently for a long time.

To use, tag resources in the app with keywords. Then these resources can be downloaded at a later time by using those tags. Even better, this can be debugged in Xcode. Using the new NSBundleResourceRequest class, call beginAccessingResourcesWithCompletionHandler(_:) to access the requested resources.

SFSafariViewController

This is long overdue. Viewing web content on the iPhone is an everyday process, and I’d go so far as to say that iOS practically pioneered mobile browsing. For a long time, developers were left with the UIWebView. It could mostly get the job done, but it’s renowned for leaking memory, not having access to the nitro javascript engine, and having no access to the device’s keychain, cookies, etc.

Things were slightly better with the release of WebKit, which introduced the improved WKWebView. This version provided access to the nitro javascript engine, responsive scrolling at 60 frames per second, built-in gestures, and more. Developers still had to create a custom user interface, had no access to AutoFill, reader mode, or browsing history.

SFSafariViewController makes browsing consistent for users. It also saves developers a lot of time, as they no longer need to create their own custom browsing experiences. It’s more convenient for users, as they will have their passwords pre-filled, not have to leave the app, have their browsing history available, and more.

The best part is that using them is incredibly simple:

import UIKit
import SafariServices

class ViewController: UIViewController, SFSafariViewControllerDelegate
{

    override func viewDidAppear(animated: Bool)
    {
        super.viewDidAppear(animated)

        //Create the safari view controller
        let sfVC = SFSafariViewController(URL: NSURL(string:"https://google.com")!, entersReaderIfAvailable: true)
        sfVC.delegate = self

        //Show the browser
        self.presentViewController(sfVC, animated: true, completion: nil)

    }

    //Delegate method for dismissing it
    func safariViewControllerDidFinish(controller: SFSafariViewController)
    {
        dismissViewControllerAnimated(true, completion: nil)
    }
}

This will produce the following result (notice the Done button which takes users directly back to the app):


Conclusion

I’m excited about what iOS 9 is bringing to the table for both developers and users. Refinements to the user experience, such as multitasking and picture in picture, will engage existing users and attract new ones. For developers, we’ve been given tools to help meet these new expectations in our own apps with APIs such as the stack view. The public beta of iOS 9 is out and now is the time to start developing with it.

This is a list of some of my favorite APIs in iOS 9 and there are thousands more. Aside from APIs, Interface Builder has been greatly enhanced (it can now render blurs and transparency). I didn’t even mention SpriteKit, which has been improved with new frameworks. For an exhaustive list of all the changes in iOS 9, be sure to visit Apple’s documentation.

I’d be keen to hear your thoughts and feedback about iOS 9.

More:
  • Hoang Nguyen

    thanks a lot, it’s very helpful for my iOS knowledge.

    • You bet! Happy developing :-)

    • Muhammet Ali Asan

      Dear Hoang, do you have a voice recorder app in Apple Store,if so I need help to recover my datas.

  • Clouds

    ok nice, looks like we will have to work more for nothing

    • Chris Ward

      What do you mean?

      • Clouds

        I mean, we have to work more, but still no money.

  • Very informative. Thanks for sharing.

Recommended
Sponsors
Get the latest in Mobile, once a week, for free.