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, ARKit 2, and Core ML 2 — not to mentioned 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, you’ll be aware of the less glamorous, but equally exciting new technologies, like customizable user notification UI, and the new Network and Natural Language 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 and 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. (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. No, not that IOS, either.
Fast Lane (or is it Fastlane?) 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 for fast roaming, 802.11k for assisted roaming, and 802.11v for wireless configuration.
Thanks to a partnership between Apple and Cisco announced in 2015, iOS developers can opt-in to this technology by providing a service type (QoS marking) to network connections (though many high-level APIs take care of this for you automatically).
New in iOS 12,
URLRequest
objects can now set network
to
NSURLNetwork
to prioritize time-sensitive requests:
import Foundation
let url = URL(string: "https://example.com/checkout")!
var request = URLRequest(url: url)
request.http Method = "POST"
request.network Service Type = .responsive Data // Prioritize
URLSession.shared.data Task(with: request) {
(data, response, error) in
…
}
This option is currently undocumented, but the guidance from the engineers presenting WWDC 2018 Session 714: “Optimizing Your App for Today’s Internet” 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
ndef
property added to NSUser
.
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 to the rest of the world).
Perhaps the most commonly advertised use cases for both technologies 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 and this article.
Matching Contacts on Phone Number and Email Address
The Contacts framework was introduced in iOS 9 and macOS El Capitan as a modern replacement for the AddressBook framework.
Until recently,
you could only search for contacts by name and identifier.
With iOS 12, you can now use the
predicate
,
and predicate
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 CNContact
,
specify a compound “AND” predicate created from the individual subpredicates,
and pass that to the enumerate
method
called on the current CNContact
:
import Contacts
let phone Number = CNPhone Number(string Value: "+1 555 555 1234")
let phone Number Predicate = CNContact.predicate For Contacts(matching: phone Number)
let email Predicate = CNContact.predicate For Contacts(matching Email Address: "[email protected]")
var fetch Request = CNContact Fetch Request(keys To Fetch: [
CNContact Given Name Key as CNKey Descriptor,
CNContact Family Name Key as CNKey Descriptor
])
fetch Request.predicate =
NSCompound Predicate(and Predicate With Subpredicates: [
phone Number Predicate,
email Predicate
])
let store = CNContact Store()
try store.enumerate Contacts(with: fetch Request) { (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
CLLocation
now has something just for you in iOS 12.
The activity
property
has been around for a while,
but remains a lesser-known configuration option for CLLocation
.
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,
walking / running / biking,
what have you.
But in iOS 12,
you can specify the
airborne activity type
and let your app’s motion tracking algorithms soar!
import Core Location
let manager = CLLocation Manager()
manager.activity Type = .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: is
.
import UIKit
// i OS 12+
UIDevice.current.orientation.is Flat
// i OS <= 11.4
UIDevice.current.orientation == .face Up ||
UIDevice.current.orientation == .face Down
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
text
property
for controls conforming to the UIText
protocol —
namely UIText
and UIText
.
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:
UIText
and
UIText
.
When you specify the .new
content type
in conjunction with
the password
property ,
Password AutoFill can automatically generate new passwords
according to the login requirements of the system.
text Field.text Content Type = .new Password
text Field.password Rules = .init(descriptor:
"allowed: ascii-printable; minlength: 8;"
)
When you specify the .one
content type,
the text field can automatically forward
two-factor authentication codes received via SMS.
text Field.text Content Type = .one Time Code
That wraps up this round of iOS 12 diff spelunking. Of course, this is an enormous release, so we look forward to cover 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!