# iOS 12

By [Mattt](https://nshipster.com/authors/mattt).
Published 2018-09-17.
Canonical URL: <https://nshipster.com/ios-12>

If you tuned in to this year’s WWDC Keynote, you’ll know all about the big features in iOS 12: [Siri Shortcuts](https://developer.apple.com/documentation/sirikit#2979425), [ARKit 2](https://developer.apple.com/arkit/), and [Core ML 2](https://developer.apple.com/machine-learning/) — not to mention the bombshell pre-announcement of the long-rumored iOS / Mac bridge, codenamed “Marzipan”.

And if you watched this year’s [Platforms State of the Union session](https://developer.apple.com/videos/play/wwdc2018/102/), you’ll be aware of the less glamorous, but equally exciting new technologies, like [customizable user notification UI](https://developer.apple.com/documentation/usernotificationsui/), and the new [Network](https://developer.apple.com/documentation/network) and [Natural Language](https://developer.apple.com/documentation/naturallanguage) frameworks.

But here at NSHipster, we’re interested in the nitty-gritty: the small (dare we say, _obscure_?) changes that add up to make a big impact to our day-to-day. This year’s [iOS 12 release notes](https://developer.apple.com/documentation/ios_release_notes/ios_12_release_notes) and [Foundation Release Notes](https://developer.apple.com/documentation/ios_release_notes/ios_12_release_notes/foundation_release_notes) cover many of these changes, however they don’t tell the whole story. For that, you have to dig deeper.

In celebration of this week’s release of iOS 12, we’re sharing what we found after trawling through the [API diffs from iOS 11.4 to 12](http://codeworkshop.net/objc-diff/sdkdiffs/ios/12.0/). (As it were, many of these are still undocumented, so proceed with caution).

---

## Prioritizing Network Traffic for Important Requests

Have you heard of Fast Lane for iOS? No, not that [fastlane](https://fastlane.tools/). No, not that [IOS](https://www.cisco.com/c/en/us/products/ios-nx-os-software/ios-technologies/index.html), either.

[Fast Lane](https://developer.cisco.com/site/fast-lane/) (or is it [Fastlane](https://www.cisco.com/c/dam/en/us/td/docs/wireless/controller/technotes/8-3/Optimizing_WiFi_Connectivity_and_Prioritizing_Business_Apps.pdf)?) is a mechanism used to prioritize wireless traffic according to its type, such as audio, video, or background data. It’s a technology specific to Cisco routers (which account for about half of all internet traffic), that encapsulates several Wi-Fi standards like [802.11r](https://en.wikipedia.org/wiki/IEEE_802.11r-2008) for fast roaming, [802.11k](https://en.wikipedia.org/wiki/IEEE_802.11k-2008) for assisted roaming, and [802.11v](https://en.wikipedia.org/wiki/IEEE_802.11v) for wireless configuration.

Thanks to a partnership between Apple and Cisco [announced in 2015](https://newsroom.cisco.com/press-release-content?type=webcontent\&articleId=1715414), iOS developers can opt-in to this technology by [providing a service type (QoS marking)](https://developer.cisco.com/site/fast-lane/) to network connections (though many high-level APIs take care of this for you automatically).

New in iOS 12, `URLRequest` objects can now set `networkServiceType` to [`NSURLNetworkServiceTypeResponsiveData`](https://developer.apple.com/documentation/foundation/nsurlrequestnetworkservicetype/nsurlnetworkservicetyperesponsivedata?language=objc) to prioritize time-sensitive requests:

```swift
import Foundation

let url = URL(string: "https://example.com/checkout")!
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.networkServiceType = .responsiveData // Prioritize

URLSession.shared.dataTask(with: request) {
    (data, response, error) in
    <#…#>
}
```

This option [is currently undocumented](https://developer.apple.com/documentation/foundation/nsurlrequestnetworkservicetype/nsurlnetworkservicetyperesponsivedata?language=objc), but the guidance from the engineers presenting [WWDC 2018 Session 714: “Optimizing Your App for Today’s Internet”](https://developer.apple.com/videos/play/wwdc2018/714/) is to use this feature judiciously, only when time is of the essence. The example they provide is “the checkout page for a shopping app”, but you can extrapolate other potential use cases.

## Reading NFC Tags in the Background

One of the longstanding questions coming out of WWDC 2018 was the new [`ndefMessagePayload`](https://developer.apple.com/documentation/foundation/nsuseractivity/2968463-ndefmessagepayload) property added to `NSUserActivity`. At the time, the most that Apple engineers would offer during Lab sessions was “no comment”.

But all became clear with last week’s announcements of the iPhone XS, iPhone XS Max and iPhone XR. These devices support reading NFC tags in the background, and if you’re running iOS 12 on the latest generation of devices, you’ll be able to — among other things — launch apps, start calls, and open URLs in response to scanning compatible NFC tags. No additional setup required. To avoid inadvertent activation, this only works if the iPhone is unlocked and not currently in Airplane Mode or being used for Apple Pay or camera.

With this NFC integration, Apple hopes to fully realize past promises made about BLE iBeacons back in 2013, offering a sleeker interface to the real world than the depravity of scanning a QR code (a practice ubiquitous in China, but largely ignored by the rest of the world).

Perhaps the most commonly advertised use cases for both NFC and iBeacon technologies have been visiting a museum and getting additional details about an exhibit by hovering your phone near a strategically-placed information placard.

Enabling this kind of functionality in your app requires entitlements, setting associated domains, and other configuration — not to mention the actual APIs you need to implement. Fortunately, Apple provides some extensive documentation for this process, including [this sample code project](https://developer.apple.com/documentation/corenfc/building_an_nfc_tag_reader_app?changes=latest_minor) and [this article](https://developer.apple.com/documentation/corenfc/adding_support_for_background_tag_reading?changes=latest_minor).

## Matching Contacts on Phone Number and Email Address

The [Contacts framework](https://developer.apple.com/documentation/contacts) was introduced in iOS 9 and macOS El Capitan as a modern replacement for the [AddressBook framework](https://developer.apple.com/documentation/addressbook).

Until recently, you could only search for contacts by name and identifier. As of iOS 11, you can use the [`predicateForContacts(matching:)`](https://developer.apple.com/documentation/contacts/cncontact/3020511-predicateforcontacts), and [`predicateForContacts(matchingEmailAddress:)`](https://developer.apple.com/documentation/contacts/cncontact/3020510-predicateforcontacts) class methods on `CNContact` to construct predicates for matching on phone numbers and email addresses.

For example, if we wanted to retrieve the given and family name components for all contacts with a given phone number and email address, you create a `CNContactFetchRequest`, specify a compound “AND” predicate created from the individual subpredicates, and pass that to the `enumerateContacts(with:)` method called on the current `CNContactStore`:

```swift
import Contacts

let phoneNumber = CNPhoneNumber(stringValue: "+1 555 555 1234")
let phoneNumberPredicate = CNContact.predicateForContacts(matching: phoneNumber)

let emailPredicate = CNContact.predicateForContacts(matchingEmailAddress: "johnny@example.com")

var fetchRequest = CNContactFetchRequest(keysToFetch: [
    CNContactGivenNameKey as CNKeyDescriptor,
    CNContactFamilyNameKey as CNKeyDescriptor
])

fetchRequest.predicate =
  NSCompoundPredicate(andPredicateWithSubpredicates: [
    phoneNumberPredicate,
    emailPredicate
])

let store = CNContactStore()
try store.enumerateContacts(with: fetchRequest) { (contact, _) in
    <#…#>
}
```

## Updating Location While Airborne

iPads are especially popular among pilots, who use them for navigation and flight planning. If you’re working on an app geared for folks up in the cockpit, you’ll be delighted to hear that `CLLocationManager` now has something just for you in iOS 12.

The [`activityType` property](https://developer.apple.com/documentation/corelocation/cllocationmanager/1620567-activitytype) has been around for a while, but remains a lesser-known configuration option for `CLLocationManager`. If you use a location manager to track changes in position over time, a quick “low-hanging fruit” optimization is to specify how you expect users to be perambulating. Until now, these modes of transportation have been strictly terrestrial: [automotive](https://developer.apple.com/documentation/corelocation/clactivitytype/automotivenavigation), [walking / running / biking](https://developer.apple.com/documentation/corelocation/clactivitytype/fitness), [what have you](https://developer.apple.com/documentation/corelocation/clactivitytype/other). But in iOS 12, you can specify the [airborne activity type](https://developer.apple.com/documentation/corelocation/clactivitytype/clactivitytypeairborne?language=objc) and let your app’s motion tracking algorithms soar!

```swift
import CoreLocation

let manager = CLLocationManager()
manager.activityType = .airborne // ✈️
```

## Detecting Flat Device Orientation

Have you ever wanted to determine whether an iOS device was laying flat on a surface, but were loath to do _two_ equality checks in the process? Good news! In iOS 12, there’s a new convenience property: `isFlat`.

```swift
import UIKit

// iOS 12+
UIDevice.current.orientation.isFlat

// iOS <= 11.4
UIDevice.current.orientation == .faceUp ||
  UIDevice.current.orientation == .faceDown
```

## Auto-filling New Passwords and One-Time Codes in Text Fields

Apple goes to heroic lengths to make user input pleasant on iOS devices. Yet despite their best efforts, the fact remains: the experience of typing on a featureless piece of smooth glass is always going to pale in comparison to a proper hardware keyboard (discontentment about the latest MacBook models notwithstanding).

To minimize the amount of text-entry drudgery, iOS 10 introduced the [`textContentType`](https://developer.apple.com/documentation/uikit/uitextcontenttype) property for controls conforming to the `UITextInputTraits` protocol — namely `UITextField` and `UITextView`. By providing one of the enumeration values you declare the semantic value of the control, which allows for details like certain name and address components to be auto-filled based on the current user’s information.

iOS 12 and tvOS 12 expand on this by adding two new content types: [`UITextContentTypeNewPassword`](https://developer.apple.com/documentation/uikit/uitextcontenttype/2980929-newpassword) and [`UITextContentTypeOneTimeCode`](https://developer.apple.com/documentation/uikit/uitextcontenttype/2980930-onetimecode).

When you specify the `.newPassword` content type in conjunction with [the `passwordRules` property ](https://nshipster.com/uitextinputpasswordrules/), Password AutoFill can automatically generate new passwords according to the login requirements of the system.

```swift
textField.textContentType = .newPassword
textField.passwordRules = .init(descriptor:
    "allowed: ascii-printable; minlength: 8;"
)
```

When you specify the `.oneTimeCode` content type, the text field can automatically forward two-factor authentication codes received via SMS.

```swift
textField.textContentType = .oneTimeCode
```

---

That wraps up this round of iOS 12 diff spelunking. Of course, this is an enormous release, so we look forward to covering many more new APIs in greater depth in the weeks to come.

> Do you have any suggestions about what we should cover next? [Please get in touch via Twitter!](https://twitter.com/NSHipster/)
