Вы находитесь на странице: 1из 183

WWDC

2015

Table of Contents
1. introduction
2. App Framework
i. Adopting new trackpad feature
ii. Advanced NSOperation
iii. Advance Touch Input in iOS
iv. Best Practices for Progress Reporting
v. Building Document Based App
vi. Cocoa Touch Best Practices
vii. Creating Complications with ClockKit
viii. Getting Started with Multitasking on iPad in iOS 9
ix. Introducing safari View Controller and WKWebView updates
x. Introducing the Contacts Framework
xi. Multitasking Essentials for Media-Based Apps on iPad in iOS 9
xii. Mysteries of Auto Layout, Part 1
xiii. Mysteries of Auto Layout, Part 2
xiv. New UIKit Support for International User Interfaces
xv. Optimizing Your App for Multitasking on iPad in iOS 9
xvi. Seamless linking to your app
xvii. WatchKit In-Depth, Part 1
xviii. WatchKit In-Depth, Part 2
xix. What's new in Cocoa
xx. What's new in Core Data
xxi. What's new in HealthKit
xxii. What's new in Internationalization
xxiii. What's new in Mapkit
xxiv. Whats New in UIKit Dynamics and Visual Effects
xxv. iOS Accessilibility
3. Design
4. Developer Tools
i. App Thinning in Xcode
ii. Building Better Apps with Value Types in Swift
iii. Improving your existing apps with Swift
iv. Optimizing Swift Performance
v. Swift and Objective-C interoperability
vi. Swift in Practice
vii. What's new in LLDB
5. Distribution
i. Getting the Most out of App Analytics
ii. What's new in Managing Apple Devices
iii. Whats New in iTunes Connect
iv. iTunes Connect: Development to Distribution
6. Featured
i. Introducing watchKit for watchOS2
ii. Platform of the union
iii. What's news in Cocoa Touch
iv. What's new in swift
v. What's New in Xcode
7. Graphics and Games
i. Going Social with ReplayKit and Game Center

2
WWDC 2015

8. Media
i. Safari Extensibility: Content Blocking and Shared Links
ii. What's new in Core Image
9. System Frameworks
i. Achieving All-Day Battery
ii. Apple Pay within apps
iii. Building Responsive and Efficient Apps with GCD
iv. CloudKit JS and Web Services
v. CloudKit Tips and Tricks
vi. Introducing Search APIs
vii. Introduction to Watch Connectivity
viii. Low Energy,High Performance:Compression and Accelerate
ix. Networking with NSURLSession
x. Privacy And Your App
xi. Security and Your Apps
xii. Whats New in CloudKit
xiii. What's New in Core Location
xiv. What's new in Core Motion
xv. What's new in Network extension and VPN
xvi. What's New in Notifications

3
WWDC 2015

WWDC 2015 log book


A log book to jote down any WWDC 2015 session videos we found useful.

Little Article by NSHipster about

1. String Transformations (What's new in internationalization)


2. CLLocationManager (What's new in Core Location)
3. Swiftification on Cocoa[Touch] API including
light weight generic for objective-c
UIAppearance proxy
UIBarButtonItem.apperaanceWhenContainedInInstanceOfClasses([UINavigationController.self]).tintColor =

UIColor.redColor()

4. NSFormatters (What's new in internationalization)


NSNumberFormatter
NSDateFormatter

Apple Swift Blog - Swift 2

Highlighted new features of Swift 2

introduction 4
WWDC 2015

Adopting new trackpad feature


force touch

rename file
quicklook
dictionary

API first level

NSTableViewRowAction

springLocaled for NS Controls

AcceleratorButton / MultiLevelAcceleratorButton

doubleValue for continuous range of value maxAcceleratorLevel for discerte levels of values

quickTime
Map NSSegmentSwitchTracking.MomentaryAccelerator

NSControl -> Continuous

Force click on the control and scrolling the images faster. The data will come with a rate.

API second level

EventTypePressure

EventTypeMaskPressure

pressureChangeWithEvent

phase

stage

1 - click
2 - force click
0 - gesture release

pressure will be given when move becomes click and it drops to zero when hit click threshold (stage 1). After hit click

thresholds, the pressure will be increased from zero and hit thresholds for force click (stage 2). The pressure drops to zero

Adopting new trackpad feature 5


WWDC 2015

again and pressure keep going under stage 2.

To check parallel mouse and pressure

var associatedEventMask: NSEventMask { get }


if ((mouse.associatedEventMask.contains(.EventMaskPressure)) {
// pressure capable device
}

Spring Loading protocol

@protocol NSSpringLoadingDestination
//either one
func springLoadingEntered(NSDraggingInfo) -> NSStringLoadingOptions

func springLoadingUpdated(NSDraggingInfo) -> NSSpringLoadingOptions

@optional
func springLocalingActivated(Bool, draggingInfo: NSDraggingInfo)
func springLoadingHightlightChanged(NSDraggingInfo)

Use aligment feedback to "snap" the UI in place

API Level 3
NSPRessureConfiguration to config trackpad behavior

init and set() but not ideal as:

only valid during a drag


racing the user behavior

Preferred : NSView var pressureConfiguration

Configured before mouse down


Configured when app not responsive

Provides Haptics feedback

NSHapticFeedbackManager and protocol NSHapticFeedbackPerformer

Adopting new trackpad feature 6


WWDC 2015

[Advanced NSOperation]
NSOperation and NSOperationQueue are one of the important technology that builts on top of GCD. It is object-orientated and

provides useful features such as cancellation, priorities and dependency.

In this session, the speaker tells the audiences that how to wrap the normal code pattern in to NSOperation suclasses and
operate them in a safe and dependency networks.

Advanced NSOperation 7
WWDC 2015

Advance Touch Input in iOS


Having low latancy touch responses is one of the important factor to provide fluent user experenice of the app especailly for
the touch-intense apps like drawing apps and games. This session provides some insights for tips and new features for
enhancement of touch events handling.

Overview of the pipeline of iOS Touch and Graphic

double buffering and triple buffer

iOS 9 new features


App metal and openGL instructions will be delivered to GPU without coordination of Core Animation

//CAEAGLLayer and CAMetalLayer


//for lowest latency
layer.presentsWithTranscation = false
//For synchronizing with CA and pass the data to signal to screen all together
layer.presentsWithTranscation = true

Coalesced Touches

120Hz Touch Scan for iPad Air 2 which means double touch events captured.

touch events like touchesBegan , touchesMoved , touchesEnded , touchesCancelled

and we can retrieve previous locations similarly to coalesced touches

Advance Touch Input in iOS 8


WWDC 2015

getting coaleascedTouches..

for coaleascedTocuh in event.coalescedTouchesForTouch(touch) {


//do anything previously with primary touches
}

Touch Predication

UIEvent.predictedTouchesForTouch(touch: UITouch) -> [UITouch]?

Advance Touch Input in iOS 9


WWDC 2015

and previous location

Advance Touch Input in iOS 10


WWDC 2015

Best Practices for Progress Reporting


Progress indicators are seen everywhere in any systems such as loading webpages of browsers, installation of applications
and reminding time and tasks for user completion. NSProgress is class to accurate report the progress of work.

Documentation of NSProgress

class NSProgress {
var totalUnitCount: Int64 //total work units
var completedUnitCount: Int64 //total work units completed
var fractionCompleted: Double { get } //computed property
var indeterminate: Bool { get } // return true if totalUnitCount < 0 or completedUnitCount < 0, useful when the total work unit is
var localizedDescription: String!
var localizedAdditionalDescription: String!
var kind: NSProgressKind
}

Localization
currently only setting kind as NSProgressKindFile to change the localizedDescriptions and
localizedAdditionalDescription

Responsibilities

For Creator

updating totalUnitCount
kind
userInfo for show different descriptions
completedUnitCount

For Clients

Do not set properties of NSProgress


get totalUnitCount
get completedUnitCount
get gractionCompleted
get localizedDescriptions

Composition
Composition of progress is needed when not tracking single progress but many progress

Use a parent progress that allows childs' progress to report back via pendingUnitCount

Best Practices for Progress Reporting 11


WWDC 2015

Implicit Composition

In older system, implicit composition is used

let parentProgress = NSProgress()


parentProgress.totalUnitCount = 2
//assigning 1 unit count to child's progress to finish
parentProgress.becomeCurrentWithPendingUnitcount(1)
startDownload() //NSProgress(totalUnitCount:...)
parentProgress.resignCurrent() //completed child's progress

create with NSProgress once the child's work begins


Document it to tell others to use the child's work progress
resignCurrent mark pendingUnitCount as finished
parent's completedUnitCount is updated

Explicit

let childProgress = child.progress


let parentProgress = ...
parentProgress.addChild(childProgress, withPendingUnitCount:1)

use explicit when there are methods returning the progress


system version >= iOS 9 or OSX 10.11

Cancel, Pausing and resuming

Cancel

Best Practices for Progress Reporting 12


WWDC 2015

var cancellable: Bool


var cancellationHandler: (() -> Void)?
var cancelled: Bool { get }

calling progress.cancel() will

set cancelled to true


invoke cancellationHandler
cancel actions also pass along to children progress
Its permanent

Pausing and resuming

var pausable: Bool


var pausingHandler: (() -> Void)?
var resumingHandler: (() -> Void)?
var paused: Bool { get }

calling progress.pause() or progress.resume() will

Sets paused to true/false


Invokes the pausingHandler/resumingHandler
Pausing/resuming flows down to children

User Interface
NSProgress properties are key value observable

Add KVO observers to update your UI


Not necessarily called on main thread

//somewhere in code
progress.addObserver(self, forKeyPath: "fractionCompleted", options: [], context: &observationContext)

override func observeValueForKeyPath(keyPath: ..., object: ..., ..., context: ...) {


if context == &observationContext && keyPath == "fractionCompleted" {
NSOperationQueue.mainQueue().addOperationWithBlock {
let progress = (object as! NSProgress)
progressView.progress = Float(progress.fractionCompleted)
}
}
else {
super.observeValueForKeyPath(...)
}
}

Best Practices
Dont use fractionCompleted to determine completion
It is a float
Use completedUnitCount >= totalUnitCount (unless indetermineate or zero)
NSProgress can not be reused
make a new instance if additional progress

Best Practices for Progress Reporting 13


WWDC 2015

Dont update completedUnitCount in a tightLoop


Dont forget update to 100%

Best Practices for Progress Reporting 14


WWDC 2015

Building document based app


Related Session : Building Document Based app WWDC 2014

What is document based app

standalone
manages a list of documents
presents to user to edit etc.

Document browser
list doc in a manageful way
use thumbnails to preview the doc
show external doc like doc in iCloud
show recently accessed documents

Discovering document

NSFileManager only list the local doc, not for doc on iCloud or doc in other apps

NSMetadataQuery combines all available including local ,remote and external doc from other apps. This populate the

notification to inform hosting app for getting remote doc and any updates to the doc.

Thumbnails are generated automatically for some types of documents.

Recent List contains the document of user just worked on. Storing NSURL is not robust as the doc may be moved. Use
security scoped bookmarks as a pointer to the doc

Document Assess
NSFileCoordination for read/write lock NSFilePresenter to receive the updates whenever the document has been modified

from other parties.

Creating/Deleting new documents

Use background queue to create new doc as coordinated operations can block

Loading and Displaying documents

Reading

Strongly suggested to use UIDocument to read and write, invoke loadFromContents() in background thread and completion
on main queue

in iOS 9

Reading may requires downloading


NSProgressReporting on UIDocument protocol is used for telling how much work done.

Building Document Based App 15


WWDC 2015

Writing

Content and thumbnails are done on background threads.

if providing custom thumbnails, make sure to thread-safety classes to create the images. UIViews are not thread-safe. Use
Core graphic suggested.

Opening from other app

in iOS 8, the doc from other apps are copies. Presenting multiple copies to user is confusing.

in iOS 9, the doc may be directly reference to the another app documents as known as Open in place via
UIDocumentMenuViewController and UIDocument

Support Open in place :

add LSSupportsOpeningDocumentsInPlace key in info.plist


adopting new delegate methods

func application(app: UIApplication, openUrl url: NSURL, options: [String: AnyObject]) -> Bool {
guard let shouldOpenInPlace = options[UIApplicationOpenURLOptionsOpenInPlaceKey] as? Bool else {
return false
}
//use the external url
let newURL = shouldOpenInPlace ? url : copyFileToContain(url)
documentBrowser.openDocumentAtURL(newURL)

return true
}

Building Document Based App 16


WWDC 2015

Cocoa Touch Best Practices


Cocoa Touch is the foundation of every iOS app that builds UI and implement attracting user experience. This session
focuses on how to make use of the cocoa touch framework and aid developers in their iOS apps.

Goal
Perforamce
User Experience
Future proof
Leverage Framework
reduce maintainance costs
get improvement for free
focus time on make app special
System Versioning? target two major recent iOS version
Include version fallbacks
if systemVersion == 9.0 (wrong)

if systemVersion >= 9.0 (correct)

if available(9.0, *)

else clause if unavailable.

App Lifecycle
launch quickly!
applicationDidFinishLaunching return quickly!

Defer long running tasks


App will be killed if launching too long
Beyond App Launch (Being responsive to every input)
Not just async
Putting long running tasks into background queue
Don't take too much memory when goes into background because
the first background app spending most memory will be killed if foreground app requires more memory
In Split View , there are two forground app at the same time
the app die more easily.

View and View controllers


Avoid hard-coded layout values (dimension scales in difference devices)
Thinking of layout in terms of sizes
Size thresholds trigger major changes
Packaged in TraintsCollections
Use Properties, Not tags
collisions with other code (using int and don't know others)
No Compiler warning
No runtime error
Add property in class and use it acorss the class
Make Timing Deterministic
Do not hard code any timer to match animation time of system UI
Leverage UIViewControllerTransitionCoordinator

Cocoa Touch Best Practices 17


WWDC 2015

Animation alongside a transition


Get accurate completion timing
Support interactive and cancelable animations (WOW)

AutoLayout Best Practices


Modify Constraints Efficiently
Identify constraints that added, removed or changed
Unchanged constraints are optimized (!)
Avoid removing all constraints (since system also provide constraints to views)
Use explicit reference to the constraints
Constraints Specificity
De-duplicating constraints
the constraints does same of others.
Create flexible constraints
Avoid hard code values
V:30-[Label(==260)] is suggested as the label is not resize when the horiontal size get larger

Instead, descrive constraints using bounds

Fully specific constraints


avoid ambiguity due to underspecific
handy function for debug and testing
[UIView hasAmbigousLayout]

Call on window to reveal entire view tree


[UIView _autolayoutTrace] to find
Putting them into unit testing
( if [UIView hasAmbigousLayout] true and show [UIView _autolayoutTrace] as test report)

Table and Collection

Cocoa Touch Best Practices 18


WWDC 2015

Use self-sizing cells (intriniticContentSizes)


Fully specific constraints
thinking in the way as Width = input; height = output
Tips if the self-sizing not working
Adding height of contentView
if same as intriniticContentSizes height => ok
if not same => constraints are not set up correctly
Animating Heights Changes
change your model and reloadData , not good UX as not animated
use [tableView beginUpdates] for self-sizing or not
update model
update cell content by getting cell reference from [tableView cellForRowAtIndexPath]
[tableView endUpdates]

Custom CollectionView Layout


Sticky header in collectionView (supplyment cell)
[UICollectionView invalidationContext]

Invalidate on bounds changes


Build targeted invalidation context
repeat as necessary (as the operation are check)

Cocoa Touch Best Practices 19


WWDC 2015

Creating Complications with ClockKit


In WatchOS2 , third-party apps gain accesss to the components of the watch faces. By designing the timeline carefully, the
users of the watch can time travel to see the past events and future events if the information applies.

Getting started
There will be new extension point for watch app in Xcode 7

There are 5 families for the complication

Modular Small
Modular Large
Utilitarian Small
Utilitarian Large
Circular Small

for different watch face styles.

The layout of UI is defined. Third-party developers are required to fill the content.

Important Classes

CLKImageProvider //provides images for the complications


CLKTextProvider //provides texts for the complications

CLKImageProvider

complication only consider the alpha channel of the images

Creating Complications with ClockKit 20


WWDC 2015

//Initialize imageProvider
let imageProvider = CLKImageProvider(backgroundImage: bgImage,
backgroundColor: aColor,
foregroundImage: fgImage,
foregroundColor: CLKImageProviderForegroundColor.White)

CLKTextProvider

CLKDateTextProvider is a date formatter for complications

//Initialize date formatter with some date units


let sep23: NSDate = ...
let units = [NSCalendarUnit.Weekday,
NSCalendarUnit.Month,
NSCalendarUnit.Day]
textProvider = CLKDateTextProvider(sep23, units)

Other provider

simple text provider


time text provider for showing time text ( e.g. 2:20pm )
Time interval text provider ( 11:00 am - 12:30 pm)
Relative Date Text Provider ( 2HR 56 mins from the event happenes)

let moonset : NSDate = ... // 2:19pm


let units : NSCalendarUnit = [.Hour, .Minute]
let style : CLKRelativeDateStyle = .Natural
let textProvider = CLKRelativeDateTextProvider(date: moonset,
style: style,
units: units)

CKComplicationTemplate

Creating Complications with ClockKit 21


WWDC 2015

A concrete class for building up the complication contains:

CLKImageProvider
CLKTextProvider ( can be multiple as families available)

TimeLine
As suggested before, in WatchOS 2, the users of watch can use "Time Travel" to view the past events like stocks or future
events like the calendar events and predicted weather data. There is critical to design a reasonable timeline so that the
users would not get confused.

CLKComplicationTimelineEntry

CLKComplicationTimelineEntry contains the timestamp and CKComplicationTemplate for represent a event in a timeline for

complication display

CLKComplicationDataSource is required data source for third party developer to implement all required protocol methods.

Documentation for CLKComplicationDataSource

// return allowed direction(s) for time-travel


func getSupportedTimeTravelDirectionsForComplication(_ complication: CLKComplication,
withHandler handler: (CLKComplicationTimeTravelDirections) -> Void)

//Timeline start
func getTimelineStartDateForComplication(_ complication: CLKComplication,
withHandler handler: (NSDate?) -> Void)

//Timeline end
func getTimelineEndDateForComplication(_ complication: CLKComplication,
withHandler handler: (NSDate?) -> Void)

//The datetime of waking up and get next log of timeline


func getNextRequestedUpdateDateWithHandler(_ handler: (NSDate?) -> Void)

// timelineEntry for current


func getCurrentTimelineEntryForComplication(_ complication: CLKComplication,
withHandler handler: (CLKComplicationTimelineEntry?) -> Void)

// timelineEntries for past date


func getTimelineEntriesForComplication(_ complication: CLKComplication,
beforeDate date: NSDate,
limit limit: Int,
withHandler handler: ([CLKComplicationTimelineEntry]?) -> Void)

// timelineEntries for future date


func getTimelineEntriesForComplication(_ complication: CLKComplication,
afterDate date: NSDate,
limit limit: Int,
withHandler handler: ([CLKComplicationTimelineEntry]?) -> Void)

Creating Complications with ClockKit 22


WWDC 2015

// placeholder for first lanuch the complication


func getPlaceholderTemplateForComplication(_ complication: CLKComplication,
withHandler handler: (CLKComplicationTemplate?) -> Void)

// show the information show in lock screen or not


func getPrivacyBehaviorForComplication(_ complication: CLKComplication,
withHandler handler: (CLKComplicationPrivacyBehavior) -> Void)

Creating Complications with ClockKit 23


WWDC 2015

Getting Started with Multitasking on iPad in iOS 9


Despite the demise of iPad in recent years, Apple put many efforts to improve the user experience of iPad. Multitasking is
somewhat long-wanted feature in iPad. This session is introducing how developers to embrace the new technologies in
Multitasking.

Great article about multitasking

Related Sesssion: Multitasking Esstials for Media-based Apps on iPad in iOS 9, Optimizing Your App for Multitasking in iOS

Multitasking in your app


Slide Over

right slide over app has compact horizontal size class

Split View

Adaptivity

Adding Multitasking to your app


iPad Multitasking is enabled by default in new project

Existing app

build app with iOS 9 SDK


base SDK as Latest SDK
Support all orientations
Use Launch Storyboards
Launch Screen files launch screen xib
if app requires full screen
consider to opt out UIRequiresFullscreen key

UIScreen.bounds returns windows.bounds Only need to care The current UIWindow

* a UILayoutGuide for legible region in a UIView


* smartly adjust when windows bounds change

```UITableView.cellLayoutMarginsFollowReadableWidth

Adds margins to cell for Legibility

Change of UIKit to Multitasking


Related Sesssion: Building Adaptive apps with UIKit (WWDC14)

Orientations

//not apply for multitasking as you may be much rooms in different direction

Getting Started with Multitasking on iPad in iOS 9 24


WWDC 2015

if UIInterfaceOrientationIsLandscape(interfaceOrientation) {
}
//encourage
if view.bounds.size.width > view.bounds.size.height {
}

//encourage
if traitCopllection.horizontalSizeClass == .Regular
}

in iOS 9 no need to set frame on window as iOS 9 figure out for you so it is okay to initial UIWindow without frame

var window = UIWindow()


or
UIWindow *window = [[UIWindow alloc] init];

PresentationController Related Sesssion: Building Adaptive apps with UIKit (WWDC14)

UIAdaptivePresentationControllerDelegate te response the size changes

Popover To handle popover arrow pointing to right position, these below are suggested.

popoverPresentationController.barButtonItem = sender
OR
popoverPresentationController.sourceView = button
popoverPresentationController.sourceRect = button.bounds

Keyboard listen to the following notification when related keyboard

UIKeyboardWillShowNotification
UIKeyboardDidShowNotification
UIKeyboardWillHideNotification
UIKeyboardDidHideNotification
UIKeyboardWillChangeFrameNotification
UIKeyboardDidChangeFrameNotification

Best Practices

Consider size and size classes instead of orientation


Think about how to respond to transition
Use adaptive presentation

Making the most of multitasking


Make your app Universal iPhone and iPad
Design user experiences for Compact and Regular widths
Use Adaptivity to change between them

Strategies

1. Be flexible for all multitasking


Slide Over (Compact width)
Half screen (Compact width)
full screen (Regular width)
Rotation

Getting Started with Multitasking on iPad in iOS 9 25


WWDC 2015

2. Auto Layout
Related Session Mysteries of Auto Layout, Part 1 and Part 2
use margin and guide provided by system to have readable content regardless size classes changes

let label = UILabel()


let readableContentGuide = self.view.readableContentGuide
let constraints = [label.leadingAnchor.constraintEqualToAnchor(
readableContentGuide.leadingAnchor), label.trailingAnchor.constraintEqualToAnchor(
readableContentGuide.trailingAnchor) NSLayoutConstraint.activateConstraints(constraints)

1. Xcode Support

Using Interface builder for constraints supports


Asset Catalog is also support size classes so any resource can apply different size classes
use preview to provide live view and see how the views response to difference size classes
2. Adaptivity callbacks

override func willTransitionToTraitCollection(


newCollection: UITraitCollection,
withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator)
{
super.willTransitionToTraitCollection(newCollection,
withTransitionCoordinator:coordinator)
switch newCollection.horizontalSizeClass {
case .Compact:
// Change your UI for a compact width
case .Regular:
// Change your UI for a regular width
case .Unspecified:
break // Do nothing
}

//do below if animation is needed for size class changes


let animation = {
(context: UIViewControllerTransitionCoordinatorContext) -> Void in
// Change your UI here. It will animate from the old to the new.
}
coordinator.animateAlongsideTransition(animation, completion: nil)
}

//another callback for overriding


override func viewWillTransitionToSize(
size: CGSize,
withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator)
{
}

5: High-level API

* ```UIStackView``` *Related session Mysteries of Auto Layout, Part 1*

6: SplitViewController

Demo Project:AdaptivePhotos

Guidelines

The app cannot prevent size changes


It cannot cause size changes either
Size changes can happen at any time

Getting Started with Multitasking on iPad in iOS 9 26


WWDC 2015

Keep user oriented


After size classes change, the screen should show what it showed before size classes change.
Remember the current size class and state if needed
Performance
do little work as possible when size classes change
Completion block for slow work
In animation block , don't call layoutIfneeded
Use setNeedsLayout to mark any views and system will layout for you in the animation

Getting Started with Multitasking on iPad in iOS 9 27


WWDC 2015

Introducing safari View Controller.


In iOS9 , we have a "in-app browser" view controller called Safari view Controller.

It shares many attributes of native safari app including:

cookies shared with native safari


passowrd auto-fill
credit card auto-fill
contact card auto fill
safari reader ( and its font customization)
Content Blocking ( select certain type of elements to not show in the webView )( also new feature of iOS 9)

Pro :

fast to setup

Cons:

Read-only url on the navigation bar


Almost same UI Layout as Native safari (tint color adopts host app's tint color)

WKWebView updates in iOS 9

//securely load local files


loadFileURL(URL:NSURL, allowingReadAccessToURL readAccessURL:NSURL) -> WKNavigation?

//load data locally without remote server


loadData(data: NSData, MIMEType: String, characterEncodingName: String, baseURL:NSURL) -> WKNavigation?

var customUserAgent:String?

Introducing safari View Controller and WKWebView updates 28


WWDC 2015

Introducing the Contacts Framework


Address book frame have been using for accessing and updating user's contact books since iOS 2.0. From iOS 9, there is
a new framework called Contacts that replaces addressBook.framebook, provides object orientated interfaces and
additional features such as searching and filtering contacts.

Classes

CNContact

A object that represented a contact in the contact book

CNMutableContact

A object that represented a contact in the contact book and the properties are mutable. Used in adding and update
contacts.

CNLabeledValue

A value of a key of certain properties of CNContact

CNSaveRequest

A cooriindater to cache any adding and updating operations to contacts

Can be cache multiple actions before executing. be aware of CNMutableContact not changing when writing into Contacts

Operations

Create contact

//Create contact
import Contacts
// create mutable for adding to the contact
let contact = CNMutableContact()
contact.imageData = // profile picture as NSData
contact.givenName = "John"
contact.familyName = "Appleseed"
contact.phoneNumbers = [CNLabeledValue(
label: CNLabelPhoneNumberiPhone,
value: CNPhoneNumber(stringValue: "(408) 555-0126"))]

let address = CNMutablePostalAddress()


address.street = "774 Loma Vista Ave"
address.city = "Los Gatos"
address.state = "CA"
address.postalCode = "95032"
contact.postalAddresses = [CNLabeledValue(label: CNLabelHome,
value: address)]

let birthday = NSDateComponents()


birthday.day = 1
birthday.month = 4
birthday.year = 1988 // can omit for a year-less birthday

let saveRequest = CNSaveRequest()


saveRequest.addContact(john, toContainerWithIdentifier: nil)

Introducing the Contacts Framework 29


WWDC 2015

try store.executeSaveRequest(saveRequest)

Updating A contact

let updatedContact = contact.mutableCopy()


let newEmail = CNLabeledValue(label: CNLabelHome,
value: "john@example.com")
updatedContact.emailAddresses.append(newEmail)
let saveRequest = CNSaveRequest()
saveRequest.updateContact(updatedContact)
try store.executeSaveRequest(saveRequest)

Getting info. fron a contact

//Getting info. fron a contact


let fullName = CNContactFormatter.stringFromContact(contact, style: .FullName)
let postalString = CNPostalAddressFormatter.stringFromPostalAddress(address)

fetching user's contacts

//matching any names contains "Appleseed"


let predicate = CNContact.predicateForContactsMatchingName("Appleseed")
//getting contacts given name and family name
let keysToFetch = [CNContactGivenNameKey, CNContactFamilyNameKey]
// We can also use formatter to fetch the names
let keysToFetch = [CNContactFormatter.descriptorForRequiredKeysForStyle(.FullName),
CNContactEmailAddressesKey]
// get a instance of contact store. Don't need to strong reference
let store = CNContactStore()
//This may be a long running tasks, suggested to put the fetching into background threads
let contacts = try store.unifiedContactsMatchingPredicate(predicate,
keysToFetch: keysToFetch)
for contact in contacts {
let fullName = CNContactFormatter.stringFromContact(
contact, style: .FullName) ?? "No Name"
print("\(fullName): \(contact.emailAddresses)")
}

Availbility check

//call this to get permission of accessing contacts


CNContactStore.requestAccessForEntityType(_, completionHandler:)

//call this to check if the key available for fetching


if (contact.isKeyAvailable(CNContactPhoneNumbersKey)) {
//...
}

Contact UI
CNContactPickerViewController and CNContactViewController will replace address book ui framework

CNContactPickerViewController

must be presented, not pushed


not required contact permisson (not showing contact dislog)

Introducing the Contacts Framework 30


WWDC 2015

May return partial contacts (only the names but not the phone numbers)
Support mult-selection

//filter the contacts in the picker


let predicate = NSPredicate(format: "familyName LIKE[cd] 'parker'")
contactPicker.predicateForEnablingContact = predicate

predicateForSelectionOfContact to indicate Which contacts are returned when tapped, others push the detail card

predicateForSelectionOfProperty to indicate Which properties are returned when tapped, others perform the default action

based on CNContactProperty

Coherence between predicates and delegate methods as it does not make sense to filter the properties that you dont
want to get deleget methods

CNContactViewController

viewing contacts

//init methods for different status of contact


viewControllerForContact:
viewControllerForNewContact:
viewControllerForUnknownContact:

not required contact permisson (not showing contact dislog)

let contact = try contactStore.unifiedContactWithIdentifier(identifier, keysToFetch: [CNContactViewController.descriptorForRequiredKeys


let viewController = CNContactViewController(forContact: contact)
viewController.contactStore = self.contactStore
viewController.delegate = self
self.pushViewController(viewController)
func contactViewController(vc, didCompleteWithContact: contact) {
// do something with the modified contact
}

Introducing the Contacts Framework 31


WWDC 2015

Multitasking Essentials for Media-Based Apps on iPad in


iOS 9
Picture in Picture(PiP) is one of killer feature in iOS 9.

Great article about multitasking

Related session : Introducing AVKit in iOS 9 WWDC14 , Mastering modern media playback

Deprecated APIs in iOS 9

MPMoviePlayerController

MPMoviePlayerViewController

Replaced by AVPlayerViewController

Support PiP frameworks

AVKit
AVPlayerViewController

Set apps background mode


Audio and airplay checked
AVAudioSession.sharedInstance() AudioSession Catogory set AVAudioSessionCategoryPlayback
allowsPictureinPicture in AVPlayerViewController if you want to stop PiP

Demo project : AVFoundationPiPPlayer: Picture-in-Picture Playback with AVKit


AVFoundation

AVPictureInPictureController for custom player controls

// Check whether Picture in Picture is supported on device.


if AVPictureInPictureController.isPictureInPictureSupported() {
// Create Picture in Picture controller.
pipController = AVPictureInPictureController(playerLayer: playerLayer)!
// Set delegate.
pipController.delegate = self
}
//
// Find out whether Picture in Picture is possible.
let pipPossible = pipController.pictureInPicturePossible
// Enable/disable Picture in Picture button.
pipButton.enabled = pipPossible
//
func pipButtonTapped(sender: AnyObject?) {
// Make sure Picture in Picture is not already active.
if !pipController.pictureInPictureActive {
// Start Picture in Picture on button tap.
pipController.startPictureInPicture()
}
}
//Delegate
func pictureInPictureControllerDidStartPictureInPicture(pipController:
AVPictureInPictureController) {
// Dismiss modal video playback view controller.
dismissViewControllerAnimated(true, completion: nil)
}
func pictureInPictureController(pipController: AVPictureInPictureController,
restoreUserInterfaceForPictureInPictureStopWithCompletionHandler
completionHandler: (Bool) -> Void) {
// Present video playback view controller again.
navigationController?.presentViewController(self, animated: true) {
// Dont forget to call completion handler.
completionHandler(true)
}

Multitasking Essentials for Media-Based Apps on iPad in iOS 9 32


WWDC 2015

func pictureInPictureControllerWillStartPictureInPicture(pipController: AVPictureInPictureController) will be

called when pip is about to starty


hide player control as the controls on pip
show placeholder to indicate the media is shown in pip
func pictureInPictureControllerDidStopPictureInPicture(pipController: AVPictureInPictureController)

show player control again as pip is dismissed


hide the placeholder to show media
Demo Project : AVFounationPiPPlayer

Webkit
WKWebView supports background modes
WKWebConfiguarion to config allowsPictureinPicture default is yes

Related session : Whats New in Web Developers in WebKit and Safari


PiP almost same as background audio
reject if any violation of rules

Best Practices
iPad is now have many foreground apps
full screen to serve only primary app
slide over will deactivite the primary and show secondary app temporary
split view to show 2 apps on a screen
PiP treats as background media
How to handle different situations for shared resources like audio, video and camera
Audio
Use one configuration
Only activate session when audio is first needed
Use Ambient category for game and sound effect and it is not interrupt the audio player underlying
use secondaryAudioShouldBeSilencedHint to check if secondary audio shuld be silenced
Related session Whats New in Core Audio in WWDC 2014
Audio Session Programming Guide on developer.apple.com/iOS
Video
use different variant of videos (high-res for full screen and low-Res for PiP)
Camera
One app can use camera
Availability can charge at any time.
UIRequiresFullscreen = YES if requires whole screen as the camera view finder

UIImagePickerController

Multitasking Essentials for Media-Based Apps on iPad in iOS 9 33


WWDC 2015

use startViewCapture() return value to see if video capturing is available

AVCaptureSession
Observe AVCaptureSessionWasInterruptedNotification for interruption
AVCaptureSessionInterruptionReasonKey would give

VideoDeviceNotAvailableWithMultipleForegroundApps if other app takes camera control

Adjust UI accordingly if interruption is happened.


After interruption is completed, AVCaptureSession will be resumes automatically
AVCaptureSessionInterruptionEndedNotification for listening the interruption is ended

Demo Project : AVCam for more details

Multitasking Essentials for Media-Based Apps on iPad in iOS 9 34


WWDC 2015

Mysteries of Auto Layout, Part 1


This session sums up most of the mysteries of auto layout developers come across.

UIStackView
A powerful UIKit component to build up a complex layout without forgiving the maintainability. UIStackView is also able to
nested. Hiding the views inside the stackView will make other subviews taking views room.

//Animation with stackView


UIView.animateWithDuration(1.0) {
self.subviewToHide.hidden = !self.subviewToHide.hidden
}

Changing Constraints
Prior to iOS 9, for any referenced constraints, we have to remove and re-add the constraints to certain views in order to
make these effective or not. In iOS 9, there are activate and deactivate for the constraint to take or not into account
when layout engine performs layouting.

Never deactivate self.view.constraints as additional internal constriants added to that view

View Sizing
Use Constraints to define the size of a view Overriding intrinsicContentSize for

the size is not calculated by constraints


custom drawing
provide invalidating
calling invalidateIntrinsicContentSize so that the layout system notices the change and can recalculate the
layout.

//calculating width based on superview's width


widthConstraint = NSLayoutConstraint(item: imageView,
attribute: .Width,
relatedBy: .Equal,
toItem: self.view,
attribute: .Width,
multiplier: 0.75,
constant: 0.0)
//Calculating height based on image's width
heightConstraint = NSLayoutConstraint(item: imageView,
attribute: .Height,
relatedBy: .Equal,
toItem: imageView,
attribute: .Width,
multiplier: 1.5,
constant: 0.0)

UITableViewCell

Self-sizing needs size from constraints

Mysteries of Auto Layout, Part 1 35


WWDC 2015

Width is defined with table view cells


Constraints must determine height
Take advantage of proportions between views

Ambiguity
Not enough constraints to define the size or position of the view
Equal, non-required priorities
@"V:|-[image]-[caption](==image@751)]-1" to set the constraints' priorities

set above or below of the priorities as system uses some priorities as well
Content Priorities
Content Hugging (Hugging priorities hug content)

Content Compression Resistance (Compression resistance resists squishing)

Mysteries of Auto Layout, Part 1 36


WWDC 2015

Alignment
use firstBaseLine and lastBaseline to align the first and last of line of text of base lines

Leading and Trailing

use leading/trailing instead of left/right to help in localization as some of language are from right to left

Alignment Rects

A rect for the most important feature of the view


Ususally same as the frame
Does not change when view is transformed
Override alignmentRectInsets if needed to provide padding
get by alignmentRectForFrame:

Related Session

Mysteries of Auto Layout, Part 2


Whats New in Cocoa
Whats New in UIKit Dynamics and Visual Effects
Cocoa Touch Best Practices
Whats New in Internationalization
New UIKit Support for International User Interfaces

Mysteries of Auto Layout, Part 1 37


WWDC 2015

Mysteries of Auto Layout, Part 2


This session sums up most of the mysteries of auto layout developers come across.

The Layout cycle


Constraints change -> Deferred Layout Pass -> Application Run Loop

Constraints change

Activating or deactivating
Setting the constant or priority
Adding or removing views

Engine recomputes the layout

Engine variables receive new values


Views call superview.setNeedsLayout()

Deferred Layout Pass

Reposition misplaced views


Two passes through the view hierarchy
Update constraints
Reassign view frames
updateConstraints
Request via setNeedsUpdateConstraints()
Often not needed
Initial constraints in IB
Separate logic is harder to follow
Implement it when
Changing constraints in place is too slow
A view is making redundant changes
Traverse the view hierarchy, top-down
Call layoutSubViews()
only overriding it if constraints are insufficient
Some views have already been layied out
DO invoke super.layoutSubviews()
DO invalidate layout within your subtree
DO NOT call setNeedsUpdateConstraints() as it already done before
DO NOT invalidate layout outside your subtree as it is not under your control
DO NOT Modify constraints indiscriminately

Interacting with legacy layout (the layout before auto layout)

set translatesAutoresizingMaskIntoConstraints to false for programmatically created views in order to flag the engine to not
create constraints for autoresizing masks

IB takes care it.

Mysteries of Auto Layout, Part 2 38


WWDC 2015

Layout Constraint Creation

iOS 9 new anchor property to make the code more readable view.topAnchor.constraintEqualToAnchor(view.topAnchor,
costant:10) view.leadingAnchor.constraintEqualToAnchor(view.leadingAnchor, costant:10)

Constraining Negative Space

We often create dummy views for layouting or grouping some UI elements.

UILayoutGuide is new class in iOS 9 for representing a rectangle in layout engine

var layoutMarginsGuide: UILayoutGuide for internal padding of a view

Debugging Your Layout

Setting identifiers for constraints helps in debug


Set accessibility identifiers
Set identifiers on layout guides
(lldb) [view constraintsAffectingLayoutForAxis:1] for debugging only one axis ( 0 = horizontal , 1 = vertical)

Ambiguous Layouts

(lldb) [view _autolayoutTrace] for showing all constraints in debug logs

view.hasAmbiguousLayout() to see if the view has Ambiguous Layouts

(lldb) [view exerciseAmbiguityInLayout] for simulator running Ambiguous Layouts and (lldb) c to resume the

process
Start the debug logs from the bottom

Related Session

Mysteries of Auto Layout, Part 1


Whats New in Cocoa
Whats New in UIKit Dynamics and Visual Effects
Cocoa Touch Best Practices
Whats New in Internationalization
New UIKit Support for International User Interfaces

Mysteries of Auto Layout, Part 2 39


WWDC 2015

New UIKit Support for International User Interfaces


Designing UI for Right To Left language

Support text is not enough. Think about UI.

Right To Left User Interface Challenges


Text Navigation UI ( back button should be on right top) Gesture support Consistent to System

Enabling RTL Language

Link against iOS 9


Use Storyboard and Auto-layout, generate XLIFF and Xcode combines it automatically

Support RTL in UI Control


Demo for RTL Localization

edit scheme > application language > right to left > pseduoLanguage to try
edit > add localization
edit > export for localization XLIFF
edit > import localization

dateformatter and numberformatter also support localization for free

Custom Layout for RTL


Use leading and trailing and it auto-flipped collectionView Flow layout supports RTL

Auto Layout

Many reasons to use


Diff. Screen size
Split-screen multitasking
localization
Storyboard or in code

Use visual format or storyboard will flip leading and trailing constraints

Using explicitly for manual constraints and layout anchors

Animation

not recommended to animation x-axis if using frames


use auto layout with leading and trailing constraints instead and system handles all

Gesture recognizers

no change

New UIKit Support for International User Interfaces 40


WWDC 2015

be aware of what's being manipulated in UI


custom gesture table view cell
navigation

Demo

override gestureRecogizerShouldBegin to check if the gesture recognizers we wanted , if not we return false,

New API on UIView UIView.userInterfaceLayoutDirectionForsemanticContentAttribute(semanticContentAttribute) return


.LeftToRight

Exception and Best Practices

Exception

Not All UI flip .Unspecified Affect auto-layout leading and trailing UISemanticContentAttribute.PlayBack and
UISemantticContentAttribute.Spartial

Best Practices

Use formatters for region-appropriate formatting


Never use NSLocale or NSBundle for UI Layout branching
Leave alignment and directionality at their default values
Natural alignment in iOS 9
Natural base writing direction is default since iOS 7 in iOS 7
Do not make layout decision based on the alignment or writing direction

Exception on UIImage

func imageFlippedForRightToLeftLayoutDirection() -> UIImage flips images in RTL context without consideration of the

current context

applies to UIImageView

only for directionary images

arrows
Chevrons
Some UI icons that match layout flows

Demo

New UIKit Support for International User Interfaces 41


WWDC 2015

Optimizing Your App for Multitasking on iPad in iOS 9


In Multitasking and PiP for iOS 9, the apps are suggested to be good multitasking citizen in order to keep the best user
experience even in a resource constrainted environment. This session aims to provide useful information for adopting new
multitasking features.

Sample Code : iconReel

The Easy stuff


use instructment to find and fix memory leaks
fix retain cycles and unbound memory growth
fix inefficient algorithms like high space and time complexities

Great Performance Involves Tradeoffs


Great Performance is a trade-off between memory, CPU, Disk space, I/O and GPU.

Working Set is a set of objects and resources is required right now

Keep it small
may change based on context
Keep it bounded in terms of memory

CPU Management

Main thread's top priority is responding to user events


Don't do unnecessary work
use QoS for setting higher priority of task
use Qos overriding to boost when the lower priority task is being waited by a higher priority
providing a hint for QoS overriding
dispatch_sync() and dispatch_block_wait()

Memory Warnings

Occured when

system is under memory pressure


The app process is approaching its memory limit
Clear cache data
release images
release view controllers

API for indicating memory warning

-[UIApplicationDelegate applicationDidReceiveMemoryWarning:]

-[UiViewController didReceiveMemoryWarning]

UIApplicationDidReceiveMemoryWarningNotification

Optimizing Your App for Multitasking on iPad in iOS 9 42


WWDC 2015

DISPATCH_SOURCE_TYPE_MEMORYPRESSURE

NSCache

NSDictionary-like
Used for objects that can be regenerated on demand
Trims under memory pressure
Trims for application lifecycle change
NOT ON DISK

Advanced Adaptive Memory

Minimize dirty memory usage


use less of it
convert to purgeable as if:
automatically reclaimed when not in use
"nice to have" data can be recomputed
Maximize purgeable memory usage
NSPurgeableData

beginContentAccess considered as dirty

endContentAccess considered as purgeable

isContentDiscarded has memory been reclaimed

File data characteristics

Absolutely essential
Expensive to generate
Can be pre-computed
Static once generated

Maximize clean memory

* Data in a file can be "memory mapped" (not caching the whole file in the memory but a pointer to a location of the file location)

Optimizing Your App for Multitasking on iPad in iOS 9 43


WWDC 2015

* memory and file content must be match exactly so it is useful for read-only data
* Data can be removed and reload when needed

API for memory mapped

typedef NS_OPTIONS(NSUInteger, NSDataReadingOptions) {


NSDataReadingMappedIfSafe,
NSDataReadingMappedAlways,
};
@interface NSData (NSDataCreation)
- (nullable instancetype)initWithContentsOfFile:(NSString *)path
options:(NSDataReadingOptions)readOptionsMask
error:(NSError **)errorPtr;
@end

not useful for small chunks of data cause


fragmentation
Exhaustion

Optimizing Your App for Multitasking on iPad in iOS 9 44


WWDC 2015

Seamless linking to your app


Deep linking becomes so important for iOS 9 as it will be connecting with brand new search mechanism in iOS 9.

This video introduces universal links to the apps when they tap links on the websites.

Demo (WWDC app) tapping website links -> native app detail page

have your app handle link to your website


have your website link to your app
help your users log into you app
Linking to your app *Custom URL schemes
apps communicate with each others
Don't always map to your app
Don't work without app installed
Don't protet users' privacy!

Breakdown of a universal link

iOS looks for

http/https scheme
domain
path or path prefix
above not match -> safari

URLQueryItem to assess url easily

Getting server ready

apple-app-site-association json file

{
"applinks": {
"apps": [],
"details": {
"9JA89QQLNQ.com.apple.wwdc": {
"paths":[ "/wwdc/news/,
"/videos/wwdc/2015/*"]
}
}
}
}

Generate an SSL certificate (not by Apple)


Sign the json file with ssl

openssl smime \
-sign \
-nodetach \
- in "unsigned.json"
- out "apple-app-site-association"

upload the signed json file to https://www.example.com/apple-app-site-association

available in iOS 8

Seamless linking to your app 45


WWDC 2015

iOS 9 seed no need to sign the json

create the file


upload to the server

Getting your app ready

func application(application: UIApplication, continueUserActivity userActivity: NSUserActivity, restorationHandler:([AnyObject]!) -> vo

var webpageURL:NSURL ?

check activityType == NSUserActivityTypeBrowsingWeb

breakdown the url and treat it like deep link

use NSURLComponent

Update entitlement with associated domain add domain as : applinks:www.example.com

Best practice

Validate input
fail gracefully (show a alert to inform user etc.)
send data over HTTPS

still need HTTP? Related session : Networking with NSURLSession

Demo to adopt universal links

Advantages of using universal links

NO Flashes or bouncing through Safari


NO code required of website
Gracefully failback to Safari
platform-indepentent
No extra server round-trips
Full user privacy protections

Smart app banners (nothing new)

Using safari saved password


available iOS 8

shared web credentials


association between app and website
add entitlement
add webcredential:example.com
add webcredentials to apple-app-site-association json file

Seamless linking to your app 46


WWDC 2015

"applinks": {
"apps": [],
"details": {
"9JA89QQLNQ.com.apple.wwdc": {
"paths":[ "/wwdc/news/,
"/videos/wwdc/2015/*"]
}
}
}

"webcredentials" : {
"apps" : [ "a1234567".com.example.AppName"]
}
}

code to retrieve the password

SecRequestSharedWebCredential(nil, nil) { cfcredentials, error in


//to check if there are any existing credentials for login
// if it does , access the user name and password from cfcredentials and login (call ui in main queue)
// if it does not, show login ui(call ui in main queue)

};

update saved credentials

SecAddSharedWebCredentials("example.com", userName, password) {


error in ...
}

Generate secure password.

let password:String = SecCreateSharedWebCredentialPassword().takeRetainedValue() as String


//print it or something else.

Related session : Your app, Your website and safari

Seamless linking to your app 47


WWDC 2015

WatchKit In-depth Part 1

Architecture
in Watch OS 2, iPhone is no longer execute the watch app and watchKit Extension. Instead the watch app runs on the
watch

4 roles :

Application WKInterfaceController
Glance WKInterfaceController
Notification WKUserNotificationInterfaceController
Complication CLKComplicationDataSource

WKInterfaceController handles:

Interface properties
Menu Handling ( force touch menu)
Controller navigation and paging
Controller model presentation
Alert and action sheets
System UI - text input,video, audio

Related Session : Creating Complication With ClockKit

WatchKit In-Depth, Part 1 48


WWDC 2015

Resource And Data

Setting image

someImage.setImageNamed("image") is not available in watch OS 2

use following to set images

let image = UIImage(named: "image")


someImage.setImage(image)

Local data

Similar to iOS app local storage structure, document directory and caches directory are available for storing data.

Beware caches directory can be wiped out by system for reclaiming spaces. Document directory is purgeable but it will not
restored from backup.

guard let documentDir = fileManager.URLsForDirectory(.DocumentDirectory,


inDomains: .UserDomainMask).first else { return }

Media

Application can play media files and records audio to a file.

Extension download media files and reads recorded audio files.

Must use a shared container

Enable app groups for extension and application

use following to access the app group

let fileManager = NSFileManager.defaultManager()


let container = fileManager.containerURLForSecurityApplicationGroupIdentifier("group.myapp")!
let fileName = name.stringByAppendingPathExtension("mp4")!
//....

Transferring data

NSURLSession
Background upload and downloads
extension may not running
downloaded files must by copied
WatchConnectivity
Watch <-> Phone communication
Share data
Transfer files
Talk to each side
Related Session:Introducing Watch Connectivity

WatchKit In-Depth, Part 1 49


WWDC 2015

Migration
WatchOS 1
iOS SDK and platform
Runs on iPhone
Share framework with iOS
image caching
openParentApplication()
WatchOS 2
dedicated OS and some specific frameworks
Runs on Watch
more options on caching
Watch Connectivity for two way communication
Independent Operation
more layout and animations available
digital crown

Related session: Layout and Animation Techniques for WatchKit

New on WatchOS 2

Extension delegate
complication datasource

Existing Project : Add watchOS Application target

New project : create iOS with WatchKit App

Related Session : Building Watch Apps

WKExtensionDelegate

similar to AppDelegate of iOS,

App Lifecycle methods:

* called once on launch


* perform app init
* setup notification observers
* app is not active yet

```applicationDidBecomeActive

invoke when the app visually active


Activate timers
Update any states

* invoke before going to background


* prepare to be inactive
* save any states
* Disable running servers, timers and tasks.

### Hand off

WatchKit In-Depth, Part 1 50


WWDC 2015

```handleUserActivity

OS 1 on root WKInterfaceController
OS 2 on WKExtensionDelegate

in coming WatchOS 2

var rootInterfaceController: WKInterfaceController will be available and can be called upon receiving handoff

//WKExtensionDelegate
func handleUserActivity(userInfo: [NSObject: AnyObject]) {
let rootController = WKExtension.sharedExtension.rootInterfaceController
rootController.popToRootController()
rootController.performActionsForUserActivity(userInfo)
}
`

Open URL

WKExtension.sharedExtension().openSystemURL(systemURL) to open any system URL

Phone (tel://)
SMS (sms://)
PassKit

Notification

The notification will be routed to Apple Watch if :

iPhone is locked
Apple Watch is on wrist and unlocked

Similar to AppDelegate on iOS, WKUserNotificationInterfaceController has following methods to handle notifications :

didReceiveRemoteNotification and didReceiveLocalNotification

use WatchConnectivity to tell iPhone counterpart to schedule local notifications.

Notification Actions

handleActionWithIdentifier(identifier: String, forRemoteNotification: [NSObject: AnyObject]) and


handleActionWithIdentifier(identifier: String, forLocaNotification)

For text replies

func suggestionsForResponseToActionWithIdentifier(identifier: String, remoteNotification: [String: AnyObject] ) -> [String] {


return ["option 1", "option 2"]
}

launching from a notification with inline text input

``` func handleActionWithIndentifier(identifer: String, forReomteNotifications: [NSObject: AnyOBject], withResponseIfno:


[NSObject: AnyObject])

WatchKit In-Depth, Part 1 51


WWDC 2015

and

``` func handleActionWithWithIdentifier(identifier: String, forLocalNotification: UILocalNotification, withResponseInfo: [NSObject: Any

and check UIUserNotificationActionResponseTypedTextKey

Enhancement

Alert
func presentAlertC ontrollerWithTitle(title: String?, message: String?, preferredStyle: WKAlertControllerStyle, action:
[WKAlertAction])

.Alert display one button

.SideBySideButtonsAlert for showing two buttons side by side

.ActionSheet for two buttons in two buttons

alert also includes destructive style

WatchKit In-Depth, Part 1 52


WWDC 2015

WatchKit In depth part 2

Digital Crown
in the native apps, digital crown can control lists, pickers and volume

in WatchOS 2, WKInterfacePicker can be used accompanying with digital crown. There are 3 styles :

list style:

Stack style:

WatchKit In-Depth, Part 2 53


WWDC 2015

Sequence style:

WatchKit In-Depth, Part 2 54


WWDC 2015

we can also put the text on the top of the focused UI

WatchKit In-Depth, Part 2 55


WWDC 2015

The scroll indicator can be hidden if the context is not fit

WatchKit In-Depth, Part 2 56


WWDC 2015

Use Coordinating images for any interesting UI via digital crown

WatchKit In-Depth, Part 2 57


WWDC 2015

use picker.setItems([WKPickerItem]) to set items in the picker

use IBAction func pickerAction(selectedIndex: Int) for getting selected index

Coordinating images

layout the UI as follows :

WatchKit In-Depth, Part 2 58


WWDC 2015

and config with :

let progressImages = UIImage.animatedImageWithImages( [WKImage], duration: 0.0)

// WKImage can be initialized with local asset, remote with imageData: or draw with Core Image

progressInterfaceGroup.setBackgroundImage(progressImages)

picker.setCoordinatedAnimations( [progressInterfaceGroup, ...])

once it set up , picker will assign the background image according to current selected index.

make sure picker item generates very fast as the list can scroll though many items in a short time.

Media Playback
1. load the asset from bundle and retrieve the url
2. setup options like WKMediaPlayerControllerOptionsAutoplayKey: ,
WKMediaPlayerControllerOptionsStartTimeKey: , WKMediaPlayerControllerOptionsVideoGravityKey: (aspect ratio)

3. and present the media player controller with url and options. provide handlers for checking if the media has played to
end, the finished time and error if any

WatchKit In-Depth, Part 2 59


WWDC 2015

WKInterfaceMovie is also provided if the player required to embed in other controllers. Movie remote url, the poster(the

thumnnail image to preview) and the video gravity ( the aspect ratio)

func setupMovie() {
//movie pointer set up via storyboard
movie.setMovieURL(url)
movie.setVideoGravity(.ResizeAspectFill)
movie.setPosterImage(poster)
}

Recommended formats

Long-form audio

used for Podcases and music


routed to blue headphones if available
Glance integration with Now Playing
similar API usage with AVFoundation
enable watch app background mode - audio playback
Since watch app and extension bundle is not the same. requires App group to share the multimedia contents. Put all

WatchKit In-Depth, Part 2 60


WWDC 2015

meida in the shared container.

Sharing Data with the containing app

Audio Recoding
call the following to get recording

presentAudioRecordingControllerWithOutputURL(url, preset: .NarrowBandSpeech, maximumDuration:60.0 , actionTitle:"Send") { didSave, erro


// ...
}

and different preset for different bitrates

Security
Store the data securely with locks/unlock mode

WatchKit In-Depth, Part 2 61


WWDC 2015

No iCloud Keychain

let secret = "somethingSecert"


if let secret = secret.dataUsingEncoding(NSUnicodeStringEncoding) {
let attributes: [NString: NSObject] = [
kSecClass: kSecClassGenericPassword,
kSecAttraccessible: kSecAttrAccessibleWhenUnlocked,
kSecAttrSErvice: "myService",
kSecAttrAccount:"account name",
kSecValueData : secretData
]
SecItemAdd(attributes, nil)
}

WatchKit In-Depth, Part 2 62


WWDC 2015

What's new in Cocoa

Swiftification

Nullability

Whether values can or cannot be nil

Swift only for Yosmite and iOS 8

ready for Obj-c in El Captian and iOS 9

nonnull never nil and translated to

nullable can be nil

null_resettable property can be set to nil but would not return nil (e.g. setting nil for default values)

null_unspecified not specified

use NS_ASSUME_NONNULL_BEGIN and NS_ASSUME_NONNULL_END for surrounding any never nil values

these nullability modifiers will be translated in swift as follows:

compiler warnings raise if the nil assigning to nonnull values in Objc

In general, nil is not valid value. NSString , NSArray , NSDictionary properties are rarely nil as using emptyness to
express. @"", @{} , @[]

Document the API that accepts or return nil on what nil means

e.g.

nil on NSText's backgrounColor as "don't draw background"

nil locale in cocoa API means "non-localized"

Generics

What's new in Cocoa 63


WWDC 2015

Specify what inside of the collection

In El Captian and iOS 9 , NSArray will be as follows:

@interface NSArray<ObjectType> : NSObject


- (ObjectType) objectAtIndex:(NSUInteger)index;
- (BOOL)containsObject:(ObjectType)anObject;
- (NSArray<ObjectType> *)arrayByAddingObject:(ObjectType)anObject;

which we can declare our array

@property (copy) NSArray<NSString *> recentSearches;

warning will be rised as URL is not the type of recentSearches

//warning as NSURL is not compatible with NSString


if ([searchField.recentSearches containsObject:someURL]) ...

The below collections are supporting generics:

NSArray
NSDictionary
NSSet
NSOrderedSet
NSHashTable
NSMapTable
NSCache
NSEnumerator

Applying generic to custom collection

@interface NSArray<ObjectType> (MySortExtensions)


@property (copy) NSArray<ObjectType> *mySortedArrayByColor;
@end

kindof

sometimes we add different objects to a same collection like UIView.subviews

if we do generic on subviews like NSArray<UIView *> *subviews

and we retrieve an button from the subviews UIButton *button = myView.subviews[0] resulting an compiler warning as
UIButton is not the UIView.

having __kindof such that the collection accepts the generic classes and subclasses

__kindof is not a runtimes check

use it with consideration

safety of caller to assume that class of object


avoid when caller should do runtime type query

What's new in Cocoa 64


WWDC 2015

Error Handling

- (BOOL) writeToURL:(NSURL *)url


option:(NSDataWritingOptions)opts
error:(NSError **) error

translate to swift as

func writeToURL(url: NSURL, options: NSDataWritingOptions) throws

error parameter is removed.

error pointers becomes the error parameters in catch

do {
try data.writeToURL(url, options:[])
} catch {
presentError(error as NSError)
}

NSError and swift error used for runtimes errors

Exceptions for programming errors

out of bounds
Assertion failed

Names cleanup

typedef enum {
NSLeftTextAlignment,
...
} NSTextAlignment

becomes

typedef enum {
NSTextAlignmentLeft,
...
} NSTextAlignment

and swift calling this enum from NSTextAlignment.LeftTextAlignment to NSTextAlignment.Left

Related Session : What's new in swift / Swift and Objective-C Interoperability

AppKit

Force Touch

Related Session : Adopting New Trackpad Features

What's new in Cocoa 65


WWDC 2015

Full Screen

Related Session : Improving the Full Screen Window Experience

Auto Layout

NSStackView or UIStackView

NSLayoutAnchor

NSLayoutGuide

What's new in Cocoa 66


WWDC 2015

Related Session : Mysteries of Auto Layout, Part 1 / Mysteries of Auto Layout, Part 2/ Improving the Full Screen Window
Experience

NSCollectionView

Related Session : Whats New in NSCollectionView

Text

New system font


New APIs

monospace of the font

What's new in Cocoa 67


WWDC 2015

Related Session : Introducing the New System Fonts

New functionality and parity with iOS

//wrap around image with the text


NSTextContainer.exclusionPaths

NSTextField.maximumNumberOfLines
//allows the text becomes tighten before truncating
NSTextField.allowsDefaultTighteningForTruncation

Visual Atomicity

show the UI in a same frame

Foundation
Release notes for WWDC seed on OSX 10.11 and iOS 9

NSUndoManager

block-based undo

func registerUndoWithTarget<TargetType>(TargetType, handler: TargetType -> ())

Target here to use generic and avoid retain cycle

Sample code :

What's new in Cocoa 68


WWDC 2015

class ColorfulShape {
var undoManager : NSUndoManager?
var color = UIColor.blackColor() {
didSet {
undoManager?.registerUndoWithTarget(self) { target in
//old Value infer to type of UIColor
target.color = oldValue
}
}
}
}

NSCoder Error Handling

func decodeTopLevelObjectForKey(String) throws -> AnyObject?


func decodeTopLevelObjectOfClasses(NSSet?, forKey: String) throws -> AnyObject?

throws as decoding error Optional as decoded empty object

NSError Value Provider

We often make our own error like this :

New api for generation of error

Register NSError domain-specific user info value provider

class func setUserInfoValueProviderForDomain(String,


provider: ((NSError, String) -> AnyObject)?)

invoked when any keys missing in userInfo dict

What's new in Cocoa 69


WWDC 2015

NSProgress

more explicit management of progress reporting


new api to add child progress objects
protocol for classes can report the progress
Ability to resume

protocol NSProgressReporting {
var progress: NSProgress { get }
}

Related Session : Best Practices for Progress Reporting

NSNotificationCenter

Unregiser the observers automatically when the observers are deallocated.

NSPersonNameComponentsFormatter

Enable propert localized names formatting


styles for different forms

Related session : Whats New in Internationalization

NSString

Conditional Quotation - different locale for different quoting requirements


Simpler localized case changing and searching
Trasliteration - was Core Foundation
Adaptive (variable width) strings for UI Presentation

Related session : Whats New in Internationalization

Thermal State ( available in 10.10.3 )

observe the termal state change to lower CPU/ Memory/ GPU/ File IO using as necessary
Documentation of Thermal State

Energy Efficient Coding Recap

Documentation of Energy Efficient App

specify tolerance on NSTimers ( the time of delay of NSTimers firing events)


Wrap user-level operations with NSProcessInfo activity APIS
Schedule non-interactive tasks with NSBackgroundActivityScheduler
Perform background network with NSURLSession
Set Quality of Service (QoS) on NSOperation, NSOperationQueue

Core Data

unique constraints
Batch Deletion
other API enhancement

What's new in Cocoa 70


WWDC 2015

Related session : Whats New in Core Data

More

NSBundle on demend resources


NSDataAsset for non-media resources in asset catalogs
NSUserActivity app search support
NSURL, NSURLComponents improvement
NSFileManager unmount and eject funcitonality
dictionary[key] = nil; now does reomveObjectForKey

Accessilibilty APIs no longer raise


NSSearchField notification and centered look
NSStringDrawingContext for more powerful string drawing

What's new in Cocoa 71


WWDC 2015

What's new in Core Data


use NSFetchRequest to

Find the data


Batch size of data
Relationship prefetching (doing in memory)

Core data handles multi-writing conflicts ,migration and persistent store vs. in-memory

New API
var haspersistentChangedValues: Bool { get } in NSManagedObject marks the object are dirty and prevent false positive

func objectIDsForRelationshipNamed(key: String) -> [NSManagedObjectID] for fetching 1 to many objects

refreshAllObjects() for

1. all objects in a context,


2. preserves unsaved changes
3. managedObject ref. are still valid
4. useful to break retain cycles

class func mergeChangesFromRemoteContextSave(changeNotificationData:[NSObject : AnyObject], intoContexts contexts:


[NSManagedObjectContext])

for better tracking changes in different coordinators


fetch latest row data
handling ordering with nested contexts

var shouldDeleteInaccessibleFaults: Bool

used to delete the reference that pointing invalid objects


Default to true
Not affecting to the api with error parameters(so still have error for handling)
missing data treated as NULL/nil/0

We often need to remove the underlying database and create a new one for latest data. By doing so, that leaves many
issues such as corrupting the files and bad access to the live connections

func destroyPersistentStoreAtURL(url: NSURL, withType storeType: String,options: [NSObject : AnyObject]?) throws

used to remove database in a safer way


honors locking protocols
handles details reconfig emptied files
Journal mode, page size

What's new in Core Data 72


WWDC 2015

Need to pass same options to addToPersistentStore


switching Journal mode may result in deadlock

At the same we may need to replace one db with other

func replacePersistentStoreAtURL(destinationURL: NSURL, destinationOptions:[NSObject : AnyObject]?, withPersistentStoreFromURL sourceUR

if the destination does not exists, this will do a copy to the destination

Remove duplication
In Xcode 7, we can define what property of a model can be used as unique identifier.

Objection deletion
For current situation, if we need to delete some objects, we have to do the following 4 steps

1. fetching the objects we wanted to delete


2. mark each of the objects to delete
3. save the changes
4. repeat for more objects to delete

NSBatchDeleteRequest is new api for us to not to pre-fetching the objects with focus on deleting

on one entiy,
one or more stores and
supporting predicates with sort descriptors and offsets.

returns

result of success/ fail


count of objects deleted
object IDs of objects deleted

and limitations are:

not reflected in the context


not all validation rules are enforced
no object notification

Models Change
we often update the models as app versions advance. Migration is needed to perform for differnt versions

Problem

1. Iterating all models is cumbersome


2. forgetting to deploy model versions is dangerous
3. Automatic lightweight migrations should Just Work

What's new in Core Data 73


WWDC 2015

in iOS 9

Model caching as last-ditch effort to recover

1. NSManagedObjectModel copied to store


2. Auto updates to existing stores
3. lightweight migrations fetch the model from the store

limitation

only SQLite store


cached models is not available to explicit migrations (as developers should prepare and know how to do the migration
anyway)

API Changes
nullability in API
__kindof

generated subclass use generics for 1 to many relationships

no need to update the header for adding new properties. Instead, editing Subclass+NSMAngedProperties.h or
Subclass+NSMangedProperties.swift for adding those new properties.

init(concurrencyType:) is the designated initializer

Related session: What's new in Core Data on iOS WWDC 2011 or NSManagedObjectContext Documentation

Performance
Use instrutment to measure the performance and find the data that should not prefetch

use -com.apple.CoreData.SQLDebug 1 for show query SQL and running time

then use EXPLAIN QUERY PLAN [sql] to see the steps of the execution of sql

What's new in Core Data 74


WWDC 2015

What's new in HealthKit

New Unit Perference


User can now change the units of related data types like weight and height in iOS 8.2.

use preferredUnitsForQuantityTypes of HKHealthStore to set preferred unit type.

use HKUserPreferencesDidChangeNotification as notification key to monitor if there are any changes.

New data type in iOS 9


Watch intake
UV exposure with Fitzpatrick skin type
Basal Body Temp.
Cervical Mucus Quality
Ovulation Test Result (+ve/-ve)
Menstruation with metadata
Vaginal Spotting
Sexual Activity

Change of HKObject
source of HKObject had been removed.

Added sourceRevision for storing sourceRevision and source with that object

Added new device property for storing related health devices information. use class function localDevice() for getting
the current device's information.

New predicate for query


HKQuery is added for querying HealthKit databases

Deletion of HKObject
deleteObjects is added for deleting multiple HKObject

deleteObjectsOfType(objectType:predicate:completion) for deleting objects fits the predicate

Querying deleted object


No easy way for tracking deleted object in iOS 8

HKAnchoredObjectQuery for query all sample with predicate provided. The result also includes delete objects for developers

to sync their app databases.

What's new in HealthKit 75


WWDC 2015

Background delivery invoke enableBackgroundDeliveryForType of HKHealthStore for sending info to third parties app.

Updating
use updateHandler of HKAnchoredObjectQuery to be informed whenever there are updates.

HealthKit in WatchOS
Same API
Assess to activity and workout data
New workout api
data syncs to companion device

Steps:

1. Request authorization for workout data types (like walking and running)
2. Start the HKWorkoutSession
3. Retrieve streamed samples from HKAnchoredObjectQuery
4. Save the HKWorkout and related sample

What's new in HealthKit 76


WWDC 2015

What's new in internationalization

Localization
preferred language

if the app is not support the language, fall to second until the app support

new customize number system

use numberFormatter to get it for free

In previous WWDC , localizing with xcode 6 that introduce XLIFF files that allows external translators to provide translations
without developers worrying about the format.

introduction

in swift NSLocalizedString to get simple localized strinng

String.localizaedStringWithFormat(format, args) to get localized formatted string

String.localizedStringWithFormat(NSLocalizedString("Location: %@"), string, string) for combination of both above

Language Ordering

sometimes it does not makes for foreign speaker to understand our language ordering

let str = String.localizedStringWithFormat(


NSLocalizedString("copy %@s %@",
comment: "copying item from user"),
"hairForce1", "photos")
en.lproj
"Copy %@s %@" = "Copying %@s %@";
//this will gives "Copying hairForce1's photos
de.lproj
"Copy %@s %@" = "%@ von %@ kopieren";
//hairForce1 von photos kopieren
(Translation : Copy HairForce1 from photos) is not make sense
"Copy %@s %@" = "%$2@ von %$1@ kopieren";
//This will change the ordering and becomes "photos von hairForce1 kopieren" which is "Copying hairForce1's photos"

Never access the language directionaries

use below for proper localized asset.

NSBundle.mainBundle().imageForResource("stopSign")
NSBundle.mainBundle().pathForSoundResource("greeting")
NSBundle.mainBundle().URLForResource("help", withExtension: "pdf")

Using stringsdict for localizing Pluralization

Every language has different style for quality of one or more. Different rules becomes a issues and requires specific logics

What's new in Internationalization 77


WWDC 2015

to handle. iOS provides the stringsdict file for handling this kind of problem.

Refer to Internationalization and localization Guide Appendix C stringsdict File Format

Variable Width

in iOS 9, we can set different strings for displaying in different device widths without using autolayout.

<key>Welcome</key>
<dict>
<key>NSStringVariableWidthRuleType</key>
<dict>
<key>20</key>
<!-- show "hi" in iPod Touch>
<string>Hi</string>
<key>25</key>
<!-- show "welcome" in iPhone>
<string>Welcome</string>
<!-- show "Welcome to the store!" in iPad>
<key>50</key>
<string>Welcome to the store!</string>
</dict>
</dict>

Formatting

Number format

in English , we use "." as showing decimal places. In German, the dot is use to separate the thousands. In order to handle
this,

//showing 3.142 in english and 3,142 in German


let pi = String.localizedStringWithFormat("%.3f", M_PI)

different style for showing currencies

What's new in Internationalization 78


WWDC 2015

Date Format

Again, date formats of US differs from Italians.

let df = NSDateFormatter()
df.dateStyle = .ShortStyle
df.timeStyle = .ShortStyle
//this will print suitable format for different language.
print(df.stringFromDate(NSDate())
//available in iOS 8
df.setLocalizedDateFormatFromTemplate("yyyyMMddjjmmss")

Weight Format

for example we have to show weight of 6 pounds to Italian weight unit. We don't know the metric of Italian so we have to
find out and do the convert on our own. Instead, we can use NSMassFormatter to format the unit and the number correctly.

let weight = 20.0 // weight in metric units


let massFormatter = NSMassFormatter()
massFormatter.unitStyle = .Long
let formatted =
massFormatter.stringFromKilograms(weight)
//shows 44.092 pounds in EN-US and 20.0 in Italian
print(formatted)

Name Format

NSPersonNameComponents and NSPersonNameComponentsFormatter are useful classes when we need to format the names

properly in different languages

let components = NSPersonNameComponents()

What's new in Internationalization 79


WWDC 2015

components.givenName = "Grace"
components.middleName = "Murray"
components.familyName = "Hopper"
//Russian
let components = NSPersonNameComponents()
components.givenName = ""
components.middleName = ""
components.familyName = ""
//set up the formatter
let formatter = NSPersonNameComponentsFormatter()
formatter.style = .Short
formatter.stringFromPersonNameComponents(components)

the result as follows:

Handling Text

when we do enumeration on string that contains emoji, this may gives unexpected result as there are multiple characters to
compose the emoji.

we should this method to loop through the string

let str = "test "


str.enumerateSubstringsInRange(str.startIndex ..< str.endIndex,
options: .ByComposedCharacterSequences) {
(substring, substringRange, enclosingRange, stop) -> () in
print("\(substring)")
}
result:
Optional("t")
Optional("e")
Optional("s")
Optional("t")
Optional(" ")
Optional("")

What's new in Internationalization 80


WWDC 2015

Case change

sometimes we change the cases of the string. The capped letter might not to reasonable for non-english speakers.

we should use:

let str = "istanbul"


//this will capitalized the proper letter which makes sense for the locale
print(str.localizedCapitalizedString)
//other related function..
print(str.localizedUppercaseString)
print(str.localizedLowercaseString)

Searching text

special character can not be searched by other language

let str = "ber"


//this will return nil as not matching
print(str.rangeOfString("uber"))
//use below for implicitly converting u to
//printing 0..<4
// available from 9.0
print(str.localizedStandRangeOfString("uber"))
//true
// available from 9.0
print(str.localizedStandardContainsString("uber"))

Transliteration

let transliterated = "".stringByApplyTransform(NSStringTransformToXMLHex, reserve: false)


// &#x1F44D;
print(transliterated)

Layout
Full suport for right to left language
Dynamic Type
Use auto-layout and double-length presuo-language to try

side note : do not hard code the tableViewCell height as different languages requiring diff. heights for show the text

What's new in Internationalization 81


WWDC 2015

Related session : New UIKit Support for International User Interfaces WWDC 2015

What's new in Internationalization 82


WWDC 2015

What's new in MapKit

Enhancement on API

Customization Pin color

pinTintColor for custom pin color

Callout customization

"popup" when tapping on pin

New detailCalloutAccessoryView for support auto-layout or stackview as complex layout inside of callout

it precedence to the subtitle if the detailCalloutAccessoryView is not nil

Map customization

mapView.showsTraffic to show traffic

mapView.showsScale to show scale

mapView.showsCompress to show compress

Timezone support

CLGeocoder
MKLocalSearch

Swift support

WatchKit Support

Traffic
MKDirectionsTransportType for selecting transport type

New transport type : Transit

ETA Request

//retrieving ETA to a POI


func getTransitETA(){
let request = MKDirectionsRequest()
/* Set Source */
/* Set Destination */
//Set Transport Type to be Transit
request.transportType = MKDirectionsTransportType.Transit
let directions = MKDirections(request: request)
directions.calculateETAWithCompletionHandler { response, error in
// Handle Response

What's new in Mapkit 83


WWDC 2015

}
}
//opening native maps for getting transit guides
func openInMapsTransit(coord:CLLocationCoordinate2D) {
var placemark = MKPlacemark(coordinate:coord, addressDictionary: nil)
var mapItem = MKMapItem(placemark: placemark)
let launchOptions = [MKLaunchOptionsDirectionsModeKey:MKLaunchOptionsDirectionsModeTransit]
mapItem.openInMapsWithLaunchOptions(launchOptions)
}

Flyover
New Map Type: .SatelliteFlyover , .HybridFlyover

MKMapCamera Related session: WWDC 2013 Putting MapKit in Perspective

New camera init for flyover

init(lookingAtCenterCoordinate centerCoordinate: CLLocationCoordinate2D,


fromDistance distance:
CLLocationDistance,
pitch: CGFloat,
heading: CLLocationDirection)

MKOverlay

Use overlays to highlight areas of the map

Occluded by 3D buildings on Standard map type


Occluded by Flyover buildings and trees
Drawn on top of terrain (the layer still on the terrain as viewing in angle)

What's new in Mapkit 84


WWDC 2015

Whats New in UIKit Dynamics and Visual Effects


UIDynamic makes the UI to simulate physical world.

UIDynamicAnimator to Provide the overall context for animation and keep track of behaviors

behavior can be composed by different behavior as well

UIKit Dynamics
Support for non-rectangular collision bounds

enum UIDynamicItemCollisionBoundsType : Int {


case Rectangle
case Ellipse
case Path
}
//optional providing path for collisions in UIDynamicItem
optional var collisionBoundsType: UIDynamicItemCollisionBoundsType { get }
optional var collisionBoundingPath: UIBezierPath { get }

Path must be
Convex
Counter-clockwise wound
Non-self intersecting
UIDynamicItemGroup
Makes multiple dynamic items behave as one
Preserves the individual collision bounds
Dynamic items in a group must not be added to behaviors individually
A group cannot contain other groups
Concave or other complex shapes are possible
UIFieldBehaviormodels vector force fields
add to a region of the view
The field is evaluated at each point within the region
Resulting forces are applied by the animator
UIGravityBehavior is a field already!

Simplified physics, well-tuned for performance; but not for complex animations
UIDynamicItemBehavior
Customize physical properties
Applied to one or more items
var elasticity: CGFloat
var friction: CGFloat
var density: CGFloat
var resistance: CGFloat
var angularResistance: CGFloat
New var charge: CGFloat
New var anchored: Bool
UISnapBehavior
Snap a view in place
Customizable damping
Customizable snapPoint
UIAttachmentBehavior
New rope like attachment

Whats New in UIKit Dynamics and Visual Effects 85


WWDC 2015

New Fixed Attachment with attachment anchor


New Pin attachment with rotatable range
New Sliding attachment with attachment anchor
New ways to debug dynamic animations
(lldb) [view debugEnabled] to show the fields visually

debugInterval to adjust time intervals

debugAnimationSpeed to speed up or slow down the animation (it still counts so probabaly use 1x)

Visual Effects

UIVibrancyEffect

To create the content that transparent to the blur and show underneath background

let vibrancyEffect = UIVibrancyEffect(forBlurEffect:blurEffect)


let vibrancyView =UIVisualEffectView(effect:vibrancyEffect)
blurView.contentView.addSubview(vibrancyView)
vibrancyView.contentView.addSubview(label)

Animation to the bounds of UIVisualEffectView Animation to the effect of UIVisualEffectView (from style of light to dark )

UIEffectView uses offscreen pass (background task) to process the blur

1. UIEffectView captures the view underneath


2. apply blur effect
3. put the result on the capture area

To provide different snapshot,

UIView.snapshotViewAfterScreenUpdates(afterUpdates:)
UIView.drawViewHierarchyInRect(rect:, afterScreenUpdates:)
UIScreen.snapshotViewAfterScreenUpdates()

To debug the effect view, (lldb) po [myEffectView _whatsWrongWithThisEffect]

Fixing broken effects

Rearrange view hierarchy Effective for Alpha and Masking


Mask views individually
Snapshot the window or screen

UI Dynamics and Auto layout


UIKit Dynamics outside

dynamicsView.translatesAutoresizingMaskIntoConstraints = true

Auto Layout inside

innerView.leadingAnchor.constraintEqualToAnchor(dynamicsView.leadingAnchor)

Custom UIDynamicItem

Whats New in UIKit Dynamics and Visual Effects 86


WWDC 2015

Subclass NSObject
Conform to UIDynamicItem
Provide .bounds
Update constraints when .center and .transform change

Whats New in UIKit Dynamics and Visual Effects 87


WWDC 2015

iOS Accessilibility
UIAccessilibility is the framework to provide bridge for iOS system and the app.

the below six variables that voice over query to the ui elements. All system-provided control are adopted and can be
overrided to fits better cases.

exteions NSObject {
//is accessible or not
var isAccessibilityElement: Bool
//the "text" of the button or label
var accessibilityLabel: String?
//additional desciption for this control
var accessibilityHint: String?
//used in sliders or some UI perform continuous values changing
var accessibilityValue: String?
// used for custom control. categorize the control
var accessibilityTraits: UIAccessibilityTraits
// the region that being detected
var accessiblilityFrame: CGRect
}

Use Accessibility inspector to check if there are any missing VO in the elements

Use UIAccessibilityElements for additioal accessbility elements for the custom controls in the app and add them to the
controllers.

Use func accessibilityPerformMagicTap() -> Bool to do special actions

New in iOS 9 , we can receive what element is being focused and perform required actions via
UIAccessibilityElementFocusedNotification

iOS Accessilibility 88
WWDC 2015

App Thinning in Xcode


This session telling acdiences how Xcode helps to reduces the size of application at the same time maintaining same user
experiences across of all devices.

App Slicing
Slicing the app into different pieces and the suitable pieces will be downloaded according to the devices.

No additional work for developers.

On Demand Resources
Based on the app flow, some resources can be downloaded afterwards like being purchasing via IAP or beating some
game levels. ODR (On Demand Resources) helps the developers to define what resources can be downloaded in later time
and removed the resource when the resource no longer needed.

Related Session : Introducing On Demand Resources

Asset Slicing
Must use asset catalog for Asset Slicing

Device Traits

Graphics capabilities
Metal GPUFamily1
Metal GPUFamily2
Memory Level
1GB
2GB

Asset Catalog also supports named data

Store other-than-media file content


Classify depends on hardware capabilities
User NSDataAsset to retrieve content

Sprite Atlases ties full SpiriteKit integration. Auto-gen of SKTextureAtlases for image asset. Thinned appropriately.

Asset Organization

Cataloging efficient is key


Robust markup means less redundancy in sliced application variants
Dont leave assets as universal if they are only used on one device family

Workflow

Create

App Thinning in Xcode 89


WWDC 2015

What if Xcode can not used for asset production?

Export image set and data sets from existing asset pipelines

Format : XCAsset Source Artifact (Simple format strcture and JSON markup)

Requirement for integration.

Project must have an xcasset folder reference


Place any externally generated content within xcasset folder
No rules on file hierarchy

Build

Xcode Build and Run automatically thins resources for the active run destination. Supported for all simulator and device run
destinations.

Distribute

For enterprise-build, IPA-exporting will have options to export one app for all devices or for certain devices.

Make sure to tick includes manifest for over-the-air installations for generating the plist files that redirecting devices to the
thinned IPA.

App Thinning in Xcode 90


WWDC 2015

Building better apps with value type in swift


When to use Swift Struct and Classes by Mike Ash

This session provides a glance on what the value types are, explain why these types are important to Swift and how these
types solve the problems in better way.

Building Better Apps with Value Types in Swift 91


WWDC 2015

Improving your existing apps with Swift


This session used "The Element" Demo app as sample project in 2012 and enhance the UI and functionality of the app by
using swift.

This session is heavily related to Swift in Practice

Swift and Objective C


In order to interloper with Swift and Objective-C , Xcode will add a bridging header for swift files so that Obj-c class can see
the properties and methods in their scope. Make sure some caveats of using nil and custom data types.

Simply add a new swift file and Xcode will add the header file for the first time.

Adding Swift extension to extend existing Obj-c classes and enjoy benefits of Swift.

Playgrounds for prototyping


We often fix the bugs and building the app to test

Improving your existing apps with Swift 92


WWDC 2015

Use playground for reducing time of roundtrips and experiments

Availability Check
use #available(iOS 8.3, *) to have compile-time safety of APIs might not available in previous version s of system. A

Improving your existing apps with Swift 93


WWDC 2015

fallback will be also suggested by Xcode.

Map, reduce and filter


in the demo

filter used to search the elements

map to mapping the multiple rows selections to the underlying data models

reduce to all sum all selected elements' atomic masses up

Improving your existing apps with Swift 94


WWDC 2015

Optimizing Swift Performance


Use class may result in overheads of temporary retain and release as to ensure the object within the scope retained.

Using struct promotes value semantics which access the values inside of struct directly.

What if a struct has some referenced objects? Using a wrapping class to prevent copying of each referenced property.

Related Session: Building Better Apps with Values Types in Swift

Generic Specification
assume we have a min function for returning the smaller value

func min<T : Comparable>(x: T, y: T) -> T {


return y < x ? y : x
}

The compiler does not know what the T and therefore the compiler behind the scenes will translate into :

func min<T : Comparable>(x: T, y: T, FTable: FunctionTable) -> T {


let xCopy = FTable.copy(x)
let yCopy = FTable.copy(y)
let m = FTable.lessThan(yCopy, xCopy) ? y : x
FTable.release(x)
FTable.release(y)
return m }

which is involving copying and release becoming overheads.

The Swift compiler understand the context of a scope.

func foo() {
let x: Int = ..
let y: Int = ..
let r = min(x, y)
}

will reduce the copy and release and comparing values itself.

Whole module optimization


For compilation faster, the compiler make use of multiple cores of CPU and compile every source file in seperated cores.
However the compiler did not resolve the boundary of the modules and compiling safely by copying the values. Whole
module optimization is aimed to deal with this kind of situations.

Optimizing Swift Performance 95


WWDC 2015

Optimizing Swift Performance 96


WWDC 2015

Turning on whole module optimization

Optimizing Swift Performance 97


WWDC 2015

Dynamic Dispatch
Apple Swift Blog about Dynamic dispatch

final keyword

Apple Swift Doc on Inheritance

Preventing Overrides

You can prevent a method, property, or subscript from being overridden by marking it as final. Do this by writing the
final modifier before the method, property, or subscripts introducer keyword (such as final var, final func, final class
func, and final subscript).

Any attempt to override a final method, property, or subscript in a subclass is reported as a compile-time error.
Methods, properties, or subscripts that you add to a class in an extension can also be marked as final within the
extensions definition.

You can mark an entire class as final by writing the final modifier before the class keyword in its class definition (final
class). Any attempt to subclass a final class is reported as a compile-time error.

Swift compiler have to check every subclass if there are any overriding properties.

Optimizing Swift Performance 98


WWDC 2015

After making sure the var name is not available to override , we can add final to inform compiler not need to check the
subclasses of that property

private keyword

Apple Swift Access Control

mark the method are not allowed to subclass with private so the compiler does not have to check subclass methods that
being overrided

Demo of using instruments


Optimizing Swift Performance 99
WWDC 2015

Optimizing Swift Performance 100


WWDC 2015

Swift and Objective-C interoperability

Working with Objective-C

Exposed to Objective-C

All classes subclassed by NSObject, the methods will be exposed to objective-c

All methods are not private

All methods are not using swift feature

Protocol must be in @objc

Return type must be objective-c understand not (Int, String)? in Swift

anything marked as @IBOutlet, @IBAction and @NSManaged will be available in Objective-C

dynamic in swift for any property will be obversed by KVO also transfer to Obj-c

@objc for anything expose to objective-c

class CalculatorController : UIViewController {


func performOperation(op: (Double) -> Double) {
// ...
}
//swift knows diffenert function as agruments have different types but not for Obj-c. ERROR in this function
func performOperation(op: (Double, Double) -> Double) {
// ...
}
//this is okay
func performBinaryOperation(op: (Double, Double) -> Double) {
// ...
}
//not expose to swift
@nonObjc
func performOperation(op: (Double, Double) -> Double) {
// ...
}
}

Error Handling

- (id)contentsForType:(NSString *)typeName error:(NSError **)outError;

is same as

func contentsForType(typeName: String) throws -> AnyObject

which both languages can call each other

@objc enum RequestError : Int, ErrorType {

Swift and Objective-C interoperability 101


WWDC 2015

case Incomplete = 9001


}
// the enum error from Swift will give the same error in objc
NSError *error;
id result = [controller sendRequest:request error:&error];
if (!result) {
//failure MyApp.RequestError: 9001
NSLog(@"failure %@: %ld", error.domain, error.code);
return nil;
}
// Generated by Swift 2.0.
typedef NS_ENUM(NSInteger, RequestError) {
RequestErrorIncomplete = 9001
};
static NSString * const RequestErrorDomain = @"...";

nullability
use the Qualifier for better swift compatibility
helps to clarify the API should accept nil or not
Compiler gives warning if nil is not expected

Use audited Region for wrap all property are not nil

Swift and Objective-C interoperability 102


WWDC 2015

evaluate values is nullable or not first. and then all the elements in the values array must not nil

Lightweight generic of Objective C


clarity whats in the collection
Enable better compiler type checking

@property (nonatomic, strong) NSArray<NSString *> stringArray;

@property (nonatomic, strong) NSDictionary<NSString *, NSString *> stringDict;

no change to the Objective-C runtimes

Swift and Objective-C interoperability 103


WWDC 2015

Use the below to remove type arguments

NSArray<NSString *> *strings = ;


NSArray *array = ;
array = strings; // okay, drops type arguments
strings = array; // okay, adds type arguments

"KindOf" type for objective c


using __kindof to tell the instance is kind of a class or a subclass
Swift will match the same type for __kindof
No more isKindofClass checking and typecasting as the type already know

Should still use id in an API?

id has been replaced with more precise type

instancetype for returning self

typed collections
__kindof x * for "some subclass of x

id<SomeProtocol> for any type conform to SomeProtocol

Use id when there is needed for representing any objects

@property (nullable, copy) NSDictionary<NSString *, id> *userInfo;

Swift and Objective-C interoperability 104


WWDC 2015

Swift in practices

Problem: Users on Different OS Releases?


change the app to required the latest OS? no
hold back on adopting new releases? no
Adopt new feature and support older OS Release? yes

always use latest SDK to build and set Minimum deployment target for minimum supported OS release

Absence of earlier OS
framework (set the framework as optional)

//not suggested way as the class might be private in previous versions.


//or typo to make this condition true but the action caused crashes.
if([NSDataAsset class]) {
}
// not suggested as easy to typo and different syntax for from classes
if ([view responsToSelector:@selector(abc)] ) {
[view abc];
}
// not suggested as easy to typo and different syntax
if (&functionAvailableInIOS9) {
}

New Swift way to check OS Version

//Assume our min. deploy target is iOS 7


let locationManager = CLLocationManager()
//ERROR as requestWhenInUseAuthorization() not available in iOS 7
locationManager.requestWhenInUseAuthorization()
//do new version check
//compiler knows that method runs when it is iOS8 or up
if #available(iOS 8.0, *) {
locationManager.requestWhenInUseAuthorization()
}

using #available so that the compiler can help developer to check the system version safely without worrying

#available(iOS 9.0, OSX 10.11, *) to support multiple platform

Bailing out early

guard #available(iOS 9.0, *) else { return }


let asset = NSDataAsset(name: "Dragon")

Factoring the code

Method with system version requirement

class MyClass {
@available(iOS 8.0, *)

Swift in Practice 105


WWDC 2015

func functionThatWithiOS8() {
}
func otherMethod() { ... }
}
let myClass = MyClass()
myClass.otherMethod()
//must use #available to check in order to invoke
if #available(iOS 8.0 , *) {
myClass.functionThatWithiOS8()
}

Class with system version requirement

@available(iOS 8.0, *)
class MyClass {
func functionThatWithiOS8() {
}
func otherMethod() { ... }
}
//must use #available to check in order to invoke
//in iOS 7 the class is not available
if #available(iOS 8.0 , *) {
let myClass = MyClass()
myClass.otherMethod()
myClass.functionThatWithiOS8()
}

@available and Subclassing

class CustomBlurView : UIView { ... }


func makeBlurView() -> UIView {
if #available(iOS 8.0, *) {
//user newer api to make blur view
return UIEffectView(...)
}
return CustomBlurView(...)
}
let blurView = makeBlurView()

Enforcing Application Constraints

Using Enum

We normally use this have a UIImage

let appleImage = UIImage(named: "Apple")!

This comes with three issues

1. duplicated information as name is in the code and asset catalog


2. Using String as name may caused typo and compiler can not check
3. forced unwrapping

A specific enum that solves the issues with strictly typed and no force unwrapping with additional benefits:

1. centrallized constants
2. Does not pollute global namespace

Swift in Practice 106


WWDC 2015

3. must use one of the enum cases


4. not failable UIImage init

enum UIImage {
enum AssetIndentifer: String {
//in Xcode 7 beta 3, the case name will convert into String if no other value assigned
case Apple
case Orange
case Banana
...
}
//add unwrapped init
convenience init!(assetIdentifer: AssetIndentifer) {
self.init(named: assetIdentifer.rawValue)
}
}

Then we can use the enum outside

let appleImage = UIImage(assetIdentifer: .Apple)

We also have segue identifiers in each view controllers

someViewController.swift
override func prepareForSegue(segue: UIStoryBoardSegue, sender: AnyObject?) {
switch segue.identifier {
case "segue1"
case "segue2"
//error as this switch have not default case
}
}

We can use the techique before to wrap the identifer into enum. When we add a new enum case, compiler find the switch
did not handle the case

class someViewController : UIViewController {


enum SegueIdentifer: String {
case Segue1
case Segue2
case Segue3
...
}
override func prepareForSegue(segue: UIStoryBoardSegue, sender: AnyObject?) {
guard let identifier = segue.identifer,
segueIdentifer = SegueIdentifer(rawValue: identifer)
else {
//not the segue identifer we want..
}
switch segue.identifier {
case Segue1
case Segue2
// error as not all cases handled
}
}
// we add extra function that accept enum as segue
func performSegueWithIdentifer( segueIdentifer : SegueIdentifer, sender : AnyObject? ) {
preformSegueWithIdentifier(segueIdentifer.rawValue, sender)
}
}

even so, if we have multiple view controllers, the enum and segue pattern will be repeated. Instead, we can use protocol to
restrict the view controllers to have same enum and functions and we can have all logic in one place.

Swift in Practice 107


WWDC 2015

protocol SegueHandlerType {
//leverage the enum and related swift functions
typealias SegueIdentifier: RawPresentable
}

and use extension to limit what type can use this protocol

extension SegueType where Self: UIViewController, SegueIdentifer.RawValue == String {


func preformSegueWithIdentifier( segueIdentifer: SegueIdentifer, sender: AnyObject?) {
performSEgueWithIdentifier(segueIdentifer.rawValue, sender: sender)
}
func segueIdentiferForSegue(segue: UIStoryboardSegue) -> SegueIdentifer {
guard let identifer - segue.identifer, segueIdentifer = SegueIdentifer(rawValue: identifer)
else {
// invalid segue identifer..
}
return segueIdentifer
}
}

Then we set the view controllers conform that protocol

class someViewController : UIViewController, SegueHandlerType {


enum SegueIdentifer: String {
...
}
func handleAction(sender: AnyObject?) {
performSegueWithIdentifier(.Segue1, sender: sender)
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
switch segueIdentiferForSegue(segue) {
case .Segue1
case .Segue2
...
//no more error for needing default case as all enum case known and handled
}
}
}

if we add a new segue, the compiler will tell us missing handling in prepareForSegue and this promotes compiler time safety.
This also helps reusability of the protocol and helps to reduce the error as constrainting the environment.

Swift in Practice 108


WWDC 2015

What's new in LLDB


LLDB is the major debugger that Objective-c and Swift developers relies on.

Breakpoint enhancement
breakpoints can have names
Other breakpoint commands and use the names
can be set in ~/.lldbinit for default breakpoints
all debug targers inherited with default breakpoints
groupping the breakpoint with -N

Command :

Memory tracing and address Sanitizer

Type Look up

What's new in LLDB 109


WWDC 2015

use type lookup or t l to inspect the swift types

Compiler in LLDB
use p to run swift code ad hoc

p for i in (0..<3) { print(names[i]) }

will print elements in names

print how Swift work with SDK

p NSApplication.sharedApplication()

In Objc

p NSLog(@"%d", 1)

will not produce error!

p NSMakeRect(0,0,10,10)

will not produce error!

p [NSApplication sharedApplication].undoManager

will gives proper class signature.(maybe it knows instance type and generic)

to support objc lldb features, call (lldb) expr @import UIKit

Error handling in Swift

LLDB will try internally and assign a variable to the error thrown.

(lldb) expr aFunctionThatThrows()


(a.EnumError) $E0 = SeriousError

Use breakpoints to stop when the exceptions(obj-c) or error(swift) occurred

command format : breakpoint set -E (objc/swift) or br s -E (objc/swift)

for specific error in swift

command : breakpoint set -E swift -O error-type-name or br s -E swift -O EnumError

and continue to show where the error throw

What's new in LLDB 110


WWDC 2015

Presentation and data formatting

fr v and p use out-of-process formatting

data and formatter are separated


easy access to debugger's objects
Keep program state intact (not changing program)

po use in-process formatting

data and formatter are live together


easy access to the program objects
Care needed to keep the program state intact
power in playground
Four swift protocol
CustomStringConvertible
CustomDebugStringConvertible
CustomPlaygroundQuickLookable
CustomReflectable

Example in the video for these four protocols

What's new in LLDB 111


WWDC 2015

Getting the Most out of App Analytics


Why App Analytics

Provides answers
Reveal missed opportunities
and therefore build better app

Preparation
No code
No SDK
App Store and iOS 8+
Users agreed to share App Analytics to developers

Terms - Measures
App Store views - count as one when the user view the app store detailed app page
App unit - the user tapped on "get" or "price tag" button
App Sales - the amount of money of user paid the app including the app prices and in-app purchase if available.
Installations - the amount of installation of the app . if a user installed in iPhone and iPod, that will count as two
Session - the engagement of user to the app
Active device - the recent device that visit the app
Active Lst 30 Days - the device has visied the app at least once for last 30 days
In-App Purchases - the money of users spent on the in-app purchase items

Demensions
App purchase Date
App Version
Campaign
iOS Version
Platform (iPhone, iPad and iPod)
Region
Website
Crashes (New)
Paying Users (New)

Compare Measures
Product Page Conversion Rate (measuring how well of your product page)
App units / App Store Views
Average Revenue Per Paying User
Sales / Paying User
Crashes Per Session ( you don't want this ratio become 1)
Crashes / Sesssions
Session Per Active Device

Getting the Most out of App Analytics 112


WWDC 2015

Source
Identify where the users from and to

Websites

Use mobile safari to nagivate to the app detail page

Campaigns

Dedicted Campaign ID The campaign link can be generated on App Analytics.

https://itunes.apple.com/us/app/id377298193?mt=8

add below in the end

&pt=1234&ct=My_Campaign

StoreKit

//Add campaign ID with StoreKit


var vc: SKStoreProductViewController = SKStoreProductViewController()
var params = [
SKStoreProductParametersITunesItemIdentifier:myAppStoreId,
SKStoreProductParameterProviderToken:"1234",
SKStoreProductParameterCampaignToken:"My_Campaign"
]
...

Smart app banner

<meta name="apple-itunes-app" content="app-id=myAppStoreId, affiliate-data=&pt=1234&ct=My_Campaign" />

Retention

How often of the user come back to app?

Getting the Most out of App Analytics 113


WWDC 2015

What's new in Managing Apple Devices


This session highlights new features of Device enrollment program (DEP) ,VPP Managed Distribution and devices
mangement in iOS 9 and El captian.

What's new in Managing Apple Devices 114


WWDC 2015

Whats New in iTunes Connect


New in Fall, 2015

schedule app release

release app before a date if the app is approved


Testflight

Supports different builds and versions for internal and external testers
New Metrics for Testers for viewing installs, session and crashes on diff. builds and versions
New limits

Avail. this summer


iOS 9 (externnal testers)
watch OS 2 (auto switching for the devices)
On demend resources
Custom Encryption

Requires Legal document and review


ITSAppUsesNonExemptEncryption
true -> export compliance required
false -> no encryption
ITSEncryptionExportComplianceCode
set the code that apps share same encryption
Account Switching

one applee id for multiple itunes connectionn


App Siloing

grouping app for different managing team with app managers, developers and marketers

Whats New in iTunes Connect 115


WWDC 2015

iTunes Connect: Development to Distribution


This session highlights the foundations of iTunes Connect functions and how to use transporters as automatic release
tools.

Deliver as the replacement of transporter

Resources and Help


can be access without account
Developer guides
Video on everything on iTunes Connect

Common App Rejections

App Store Product Page

App Previews

Testflight enhancement

Transporter
A command line program to uploads and verifies the app meta-data and asset to iTunes Connect. The meta-data includes :

Localized screen captures for the devices


Localized app title, descriptions and what's new text
Game center related like achievement and leaderboards and images
Setting for pricing
Setting for available region for the apps

Preparation

App And version must already exists

Xcode and Application Loader are present

iOS apps and Mac apps are available to use

Steps

1. Transporter downloads the assets and met-adata


2. modify the items
3. use transporter to verify
4. if verify success, upload the modified assets and meta-data

Documents :

App Metadata Specification


Transporter User Guide

iTunes Connect: Development to Distribution 116


WWDC 2015

iTunes Connect: Development to Distribution 117


WWDC 2015

Introducing WatchKit for WatchOS2

Extensions runs on Watch


From WatchOS2, the watch app extension will run on watchOS and therefore the app become much more responsive.

Digital Crown
Digital Crown can control pickers natively. Custom controls are also supported via protocol. Coordinated Images are used
for special design like like a clock ring.

Layout and Animation


More API available that in Storyboard will be available in programmatically. Animations are supported in WatchOS2

Related Session: Layout and Animation Techniques for WatchKit

Taptic Engine
Different style of haptic can be used.

Related Session : Designing for Apple Watch

Media
There is a controller that recording voice on watch

Movie and short audio content can be played on watch.

native player controller for playing long-form or stream audio. App is not required to run in background

Alert
Alert API on watch for user confirmation. similar to AlertController

Open system URL API


sms url to reply on watch

tel url to make phone call on watch

PassKit
Add pass to watch and iPhone wallet

Related Session : WatchKit In-Depth, Part 1 and part 2

Introducing watchKit for watchOS2 118


WWDC 2015

New frameworks

ClockKit
To make complications

Related Session :Creating Complications with ClockKit

Network
Watch can directly access networks if the Phone is not present

Related Session :Networking with NSURLSession

Watch Connectivity
New framework for sync the data and files between wath and phone

Related Session : Introducing Watch Connectivity

Core Motion
Core Motion can now used in Watch. Past records can be retrieved for the app and allows querying

Related Session: What's New in Core Motion

Core Location
Watch can get location. Permission are synced with Phone. Once user approved the permission, phone follows.

Related Session : What's New in Core Location

Health Kit
Similar to Core Motion, Health Kit can be used in Watch as well. Watch can also start workout and retrieve related health
data like heart rates

Related Session : What's New in HealthKit

Security
Watch has its own keychain items. Consideration of data when the device locking or not is in related session.

Related Session : Security and Your Apps

MapKit

Introducing watchKit for watchOS2 119


WWDC 2015

Watch can retrieve directions from MapKit and used that guides user to destination.

Related Session : What's New in MapKit

Contacts
Likewise, contacts can be seen in watch.

Related Session : Introducing the Contacts Framework for iOS and OS X

Calendar
Access user's calendar via Event Kit

Introducing watchKit for watchOS2 120


WWDC 2015

102 Platform state of the union


This 2 hours long session sums up the technical aspect of latest platforms for OSX EL capitan, iOS 9 and watchOS 2.

this is a good blog post of summary for replayKit , GamePlayKit , HomeKit and Search

Xcode 7 free native development and deploy to device

Apple Developer Program merging into one for any platform and paid once only.

App thinning
App Slicing

A app bundle contains every platform resources needed.

32 bit / 64 bit
Images 1x/ 2x/ 3x
GPU shaders (low /high)

Running on a device just need one set of components

App store will deliver needed for the user and thus reducing size of apps.

if using asset catalogs, that will done automatically.

On demand resources

Sliced for device. Hosted by Apple. Downloaded when needed. Reclaimed the space where needed.

e.x. tutorial resources game-level resources..

Bitcode

intermediate binary format for submitting to app store. App Store deliver full binary and optimized with latest compiler
available.

therefore , if there are new CPU architecture , develoeprs are not needed to resubmit the app.

iOS 9 default on WatchOS 2 mandatory

Starting from iOS 9

Developers are allowed to submit 64 bit only binary.

watchOS2
Extension runs on Watch instead of on iPhone

WatchConnectivity.framework for watch connections

NSURLSession

Platform of the union 121


WWDC 2015

Customized Complication

Schedule Updates (update all local schedule data)


Push Updates

Time Travel

New feature of WatchOS2

Demo Transit to native app WatchOS1 to WatchOS2 migrator

replace openParentApplication with WatchConnectivity interact with digital crown WKInterfacePicker and WKPickerItem
Style List stack sequence

watch Simulator -> full watchOS simulator

Foundation
new compression algorithm lvfse battery improvement Security Two-factor authencitation

NSURLSession
exception domains in info.plist IPv6 support
use the networking frameworks
avoid use IPv4-specific APIs
Avoid hard coded addresses

iOS 9 submission requirement : support IPv6

internationalization
App store sales

Platform of the union 122


WWDC 2015

1. US
2. Japan
3. Chinese

new internationalizaton formatter

NSPersonNameComponentsFormatter

full support in UI elements like layout , system gestures

if use autolayout, right to left languages are supported automatically

for custom View Controller,

UIView.userInterfaceLayoutDirectionForSemanticContentAttribute()

Universal Links

1. Register app links


2. NSUserActivity ( same as hand-off )

application:continueUserActivity:restorationHandler

Search

1. App Search

CoreSpotlight
App Indexing extension
NSUserActivity
Web markup ( from the website mirroring of the app)

multitasking

SlideOver

Split View

-> Adaptive UI

pick a layout and adapt window changes

Dynamic Type
Auto layout
Size Classes

Platform of the union 123


WWDC 2015

Adopt Adaptive UI
Use a launch storyboard
Support all orientations

Picture in Picture

Support background media playback Enable picture in picture

AVPlayerViewController
WKWebview
AVPictureInPictureController

Platform of the union 124


WWDC 2015

Window Management in Mac

Force Touch
NSPressureConfguration
NSGestureRecoginzer
NSView.pressureChangeWithEvent()
NSEventType.EventTypePressure

iCloud drive native app (enable in setting)

CloudKit dashboard
Cloud Web Services
Full access via JSON
JSLibrary
Secure sign in with Apple ID

Swift 2
Open source to Linux with compilers and libraries.

Error Handling
Availability checking

if #available(iOS 9.0, *)

fluent language for generic functions

guard for early exit

Generic for Object

Xcode new feature Header file view (by removing implmentation) Rich comments

StackView hidden view inside StackView -> auto adjust

Storyboard reference > connections with different storyboard files (no need to put all scenes in a storyboard)

on demend resource tags (custom tags)

resource download orders and dwonload priorities

New Xcode profiling tools

Crash logs > open in projects > focus on crash codes

Testing

user interface testing

Platform of the union 125


WWDC 2015

Code coverage (see the proportion of codes are already tested)

right click on test cases to see test report UI testing -> record button -> auto generate UI test code

GameKit
New Xcode editor for scenes and 3d Models

Game logics

can use without game as well

Replay Kit

save game replays

can use without game as well

Platform of the union 126


WWDC 2015

What's news in Cocoa Touch


iOS 6

Autolayout

iOS 7

dynamic text

iOS 8

Adaptivitiy
Size Classes
View controllers
View controller presentations
Search Result
Action Sheets

iOS 9

Multitasking
Picture in Picture
Related Session:
Getting Started with Multitasking on iPad in iOS 9
Multitasking essentials for media-based apps on iPad in iOS 9
Optimizing Your app for multitasking in iPad iOS 9

Layout Guides UILayoutGuide

UIView
MarginLayoutGuide( available Since iOS 8)
ReadableContentMargin
Make sure the text is readable regardless of users' text size and available spaces

UIStackView

adjustable Spacing and alignment


nested

Shortcut Bar(above the keyboard)

customized via UITextInput protocal


func inputAssistantItem
leadingButtonGroup
trailingButtonGroup

Storyboard

link one storyboard to another


Unwind segue

Right to left Support

What's news in Cocoa Touch 127


WWDC 2015

UIViewController
var semanticContentAttribute (override to return value for custom layout)
UIView
var semanticContentAttribute (override to return value for custom layout)
UIImage

func imageFlippedForRightToLeft
var isFlippedForRightToLeft
Related Session :
New UIKit Support for international users interfaces
Accessibility

Change to AVSpeechSynthesis
Related Session :
iOS Accessbility

Text Editing Gesture( text selection gesture on software keyboard with two fingers dragging)

nothing to do to support
make sure custom text view gesture is not conflicting

Keyboard commands(Hold command key on hard keyboard)

set discoveryTitles and UIKit will figure out

Touch Events

reduce the latency the touch received.


Touch predictions (WOW)
Advanced Touch input on iOS 9

UIDynamic

What's news in Cocoa Touch 128


WWDC 2015

Support Ellipse and Path Collision Bounds(Only rectangle before)


UIFieldBehavoir
Linear and Radial Gravity
Spring
Drag and Velocity
Noise And turbulance
Electric and Magnetic
Or Custom field Evaluator to create own field.
new Attachment type
Fixed
Sliding
Pin
Limit

Visual Effect

Animated Blur radius

API optimizations for Swift

Nullability
Lightweight generics ( subViews are not id instead of UIVew Type)
Related Session :
Whats new in Swift

Notifications

var behavior
var action parameters

Safari

SFSafariViewController

New extension point

Packet Tunnel Provider


App Proxy Provider
Filter Control/data provider

Safari Extension point

Shared Links
Should appear shared Link
Content Blocking

SpotLight Extension point

Index of application data


Index maintenance
Related Session :
Introducing App Search

Audio Unit Extension point

What's news in Cocoa Touch 129


WWDC 2015

Related Session :
Audio unit extension

Contacts

New Swift and Objective- API


Related Session :
Introducing the contacts framework for iOS & OS X

Wallet and PassKit

Core Location

updates to background location tracking


CLLocationManager
request one-time location
func requestLocation

MapKit

access 3DPlayer flyer View


show traffic
show compress and scale
custom callouts(?)

Health Kit

Direct support in WatchOS2

ResearchKit

HomeKit

CloudKit

Related Session :
Whats new in CloudKit
CloudKit tips and tricks

UIDocument

no longer a copy of the document

On Demand Resource

Hosted on App Store


Dynamc load content
Base on history
user behaviors

App Slicing

Automatically tailors the applications


New NSDataAsset class

Game centre

What's news in Cocoa Touch 130


WWDC 2015

ReplayKit

GamePlayKit

Related Session :
Introducing GamePlayKit

WatchOS2

Related Session :
Introduction WatchKit for Watch OS 2

What's news in Cocoa Touch 131


WWDC 2015

[What's new in swift]


Great Article by Mike Ash

What's new in swift 132


WWDC 2015

What's new in Xcode


On each WWDC, Apple releases a new version of Xcode with a bunch of new features to make it more comprehensive and
developer-friendly. In WWDC 2015, Apple introduces the new Xcode 7 coming with the following features:

1. Playground
2. App Thinning
3. Watch OS Support
4. Instrument Enhancement
5. Crash Log
6. Address sanitizer
7. UI Test

Playground
Playground was first introduced in WWDC 2014. Developer can write pieces of codes (swift only) on it and get response
quickly line by line. It is very useful for prototyping and testing. In this year, Playground has new some improvements:

Playground can be divided in to several pages, developers present and group their codes nicely
Playground's documentation supports Markdown and even creates table of contents and page links. To view
markdown, go to Editor > Show Rendered Markup.

To create page link:

[Link Display Text](playground-page-name)

Next Page:

[Next Page](@next)

Previous Page:

[Previous Page](@previous)

Playground can render UIView that you can glance over what you do

App Thinning
It helps developers to deliver their app with smaller app size and let users download the on-demand content when they
need. There are 3 ways to do so:

Bitcode: Xcode will process your binary automatically by this technique. Thus, Apple own a set of processed code
which allow her to generate new app with their updated compiler or architecture in future. And developer can get rid of
app re-submission, Apple do it for you.

App Slicing: Your app is sliced in to pieces by architecture, image sets, etc. Slicing process is automatically done by
Apple after your app submission. All you need to do is put all your assets into image assets. Apple engineers say that

What's New in Xcode 133


WWDC 2015

XCAsset now supports other formats, e.g. plists, 3d modes, etc.

On Demand Resource: By tagging your assets in XCAsset, you can slicing them out of your main bundle. These
bundles are hosted by Apple. You make a bundle request when those on demand resources are going to be shown or
required.

Reference: [link]

Watch OS Support
This year, Apple puts much more effort on Apple Watch. WatchKit is separated out and become Watch OS. Xcode 7
provides an auto-migration tool for migrating from old WatchKit to Watch OS codes.

Instrument Enhancement
add energy efficency profiler
add location request profiler

Crash Log
In Xcode's organizer, a new session is about Crash Log, which is something simular to (clone?) Google Play Exception
Logger or Crashlytics. You can check the crash report from testflight users to app store users. It includes crash device
models, OS versions, crash frequency and even crashed source code position. So, developers can target the crash
issue much accurately.

Address sanitizer
AddressSanitizer (or ASan) is a programming tool that detects memory corruption bugs such as buffer overflows or
accesses to a dangling pointer (use-after-free).

Developers always face with EXC_BAD_ACCESS crash that Xcode point back to main() function. Developers can't trace
back what functions get called before. With ASan, it helps you trace back where the memory corruption is.

UI Test

What's New in Xcode 134


WWDC 2015

UI Test is supported in Xcode 7 seamlessly (before you need UIAutomation or Snapshot plugin). Developers simply start a
UI recording session which convert all user interaction as UI testing script. Moreover, developers can insert some testing
script to test the availability of UI elements and its correctness.

What's New in Xcode 135


WWDC 2015

Going Social with ReplayKit and Game Center


This session introduces with new game center features and replayKit. For now, we ignore game center as it is less likely to
use. However, ReplayKit is sure the best way to get videos of UAT testing and aid developers to fixed issues.

Quick code snippnets for using replayKit

ReplayKit
Record Audio and Visual
Ability to Add Voice commentary
HD quality
Privacy safeguard (Record screen & mic / Record Screen / disallow)
Available in iOS 9
For A7 cpu for up
No Direct access of replay video (only via share sheet)

Main functional classes


RPScreenRecorder

Start , Stop and discard recording


Check ability to record
Enable mic for commentary

RPScreenRecorderDelegate

if availability changes
if recording stops ( due to error)

RPPreviewController

preview the recording


edit and trim
Share

RPPreviewControllerDelegate

after view controller dismissal

Demobots (demo project, show other new features as well)

Fine tune the replay videos


Replay Kit may be unavailable

Airplay in use
TV-out in use
Unsupported device(like iPhone 4s iPhone 5)

Going Social with ReplayKit and Game Center 136


WWDC 2015

To solve :

use available property to check


disable recording UI (like button) if false
listen screenRecorderDidChangeAvailability for change

Discard the recording

previous recording will be discarded when new recording is started


Only one recording at a time
discardRecodingWithHandler to run anything when the recording discards.

Show UI when the recording is ongoing- like a mic and REC icon use recording propery and microphoneEnabled to
check if the RPScreenRecorder recording has these.

Excluding UI

hide elements that are uninteresting


only record main window (like recording/ virtual control / pause and menu buttons etc.)
use sepearate for those recording UI elements

When to record

App Control(embed the recording in logic)


User controller(user hit the recording button)

Going Social with ReplayKit and Game Center 137


WWDC 2015

Safari Extensibility: Content Blocking and Shared Links


This session shows how to make the Content Blocking and shared links extension. Very easy to follow by just reading the
slides.

Content Blocking
A safari extension for blocking certain kinds of content in the webpage. Use a json file to define what needed to block and
extension loads that json file.

Shared Links
The @ list next to reading list which shows feeds of links under subscribed. In iOS 9 and EL Capitan, native app can add
shared links.

Safari Extensibility: Content Blocking and Shared Links 138


WWDC 2015

Whats new in Core Image

Introduction to Core Image


CIKernel - * Represents a program written in Core Images language

CIFilter Has mutable input parameters

CIFilter Uses one or more CIKernels to create a new image based on inputs

CIImage - * An immutable object that represents the recipe for an image

CIContext - An object through which Core Image draws results

What's new
Metal
As input and output of CIImage
Core Image use Metal to render filters
Some ClFiler use Metal for performance
Filter
40 new filers for iOS Core Image
PDF417 and Code128 generators
Detectors
CIFaceDetector
CIBarcodeDetector
CIRectangleDetector
CITextDetector
Color Management
Supports ICC-based CGColorSpaceRef for input or output
Correct Rendering of TIFFs and JPGs tagged with colorspace
Improved CIKernel
New CIKernel Classes
Improved CIKernel Language
Unified implementation

Bridging Core Image with other framework


Using Metal with Core Image
New render API with commandBuffer

Bridging Core Image and AV Foundation


Core Image integrated with AVVideoComposition
Automatic color management which can be disabled
Examples:
Exporting an AVAsset applying CIFilters
Playback an AVAseet applying CIFilters

What's new in Core Image 139


WWDC 2015

Core Image Provider


UIImageView is not suggested for performance-needed applications as it renders twice in system one for CPU ad one for
GPU.

//in iOS, expose the CALayer and apply CIFiler for best performance
class MyGLKView : GLKView {
}
class MyGLView : UIView {
override class func layerClass() -> AnyClass { return CAEAGLLayer.self }
}

CLContext should create once.

Core Image With SpriteKit

Core Image With SceneKit

Core Image With Core Animation

What's new in Core Image 140


WWDC 2015

Achieving All-Day Battery

iOS 9
per-app battery usage low power mode environmental factors inteligent suggestions

Xcode
iOS energy gauge

CPU
Networking
Location
Background Location instrument

Energy = Power x time


use lesser Power -> lengthen the usage time

Eliminate polling and timers


Response to user action and being idle
Do the work later and allow delay
Batch work

Networking -

beware high,fixed power costs


Design it by using minimal cost
try to coalesced -- group the networking together and not to do long networking
Background update and use NSURLSession
use notification sparingly

Location -

Don't keep updating location unless need to


invoke startUpdatingLocation() when need to
call stopUpdatingLocation() asap
use requestLocation() in iOS 9 for a quick grab of user's location
locationManager.allowsBackgroundLocationUpdates = false to make sure the background locational update is not

performed
lower accuracy saves power
set alowDeferredLocationUpdateUntilTraveled:timeout: to give tolerance for system to perform location update while
saving power

Background operation - Don't delay "real" sleep

startBackgroundTask() keeps device awake

only start for non-trivial user work


call endBackgroundTask() asap

Achieving All-Day Battery 141


WWDC 2015

Apple Pay within apps

What is Apple Pay


Easy - no need to re-enter
Secure - use touch ID
Privacy - card number is not exposed to merchant

Developer benefit

no need to handle credit card numbers


higher conversion rates and fast checkouts
no need to create accounts

Apple Pay or in app purchase

Supported devices
iPhone 6
iPhone 6+
iPad Air 2
iPad mini 3

First Steps to Apple Pay


Apple Pay within apps 142
WWDC 2015

Merchant ID is required and created in Developer portal (in reserve DNS format)
Developer id and certificate are used to encrypt payment data

Steps of Apple Pay


1. Apple Pay Eligible?
2. Touch ID exists?
3. System creates secure information to Apple Server
4. If everything goes okay, Apple Server sends payment info. for merchant server to process
5. merchant server return success

2 way processing Payments

1. Payment platform (preferred)

handle decryption on your behalf


Simply send the payment token
some of the platform even provide SDK
easier for most of developers
2. Setup on your own services

Decrypt the payment token on server side


Futher information: PAyment Token Reference

User experience
no account setup
no lengthy form
up-to-date billing and shipping address

Integrating Apple Pay

Enable quick checkout (right into product detail)


Default to Apple Pay eligible customer
Display Apple Pay button from API
Button size should be similar to other payment button
Show the payment sheet immediately

Customize Apple Pay sheet

Request to card & billing , shipping address and contact name but do not request
Shipping options are available
List total and subtotal and discount
Make estimates payment clear
Business name next to total cost as showing charges
Show post-purchase like more information after payment sheet dismissal

Putting all together in code

Request a payment

Apple Pay within apps 143


WWDC 2015

PKPaySummaryItem
``` for all checked out products and shipping information

PKPaymentRequest ``` contains payment information

PKPaymentAutherizationViewController
``` the UI display all related information of the payment

PKPayment ``` the result of a payment

Checking for Apple Pay

let paymentNetworks = [PKPaymentNetworkMasterCard, PKPaymentNetworkVisa]


if PKPaymentAuthorizationViewController.canMakePaymentsUsingNetworks(paymentNetworks)
{
// create payment request
}
else {
// use traditional checkout flow
}

New in iOS 9 we can check if the device has debit card

PKPaymentAuthorizationViewController.canMakePaymentsUsingNetworks(networks,
capabilities: .CapabilityDebit)

Checking the hardware

PKPaymentAuthorizationViewController.canMakePayments() -> Bool

Creating a Payment

//make sure entitlement is presented


let request = PKPaymentRequest()
request.merchantIdentifier = "merchant.xxxx"
request.countryCode = "US" //in ISO
request.currencyCode = "USD" //in ISO
request.supportNetworks = [PKPaymentNetworkAmex, PKPaymentNetworkVisa]
request.merchantCapabilities = .Capability3DS
request.paymentSummaryITems = [...]

creating items

let total = PKPaymentSummaryItem(label: "MY Company", amount: NSDecimalNumber(string: "123.45")


request.paymentSummaryItems = [total]

use NSDecimalNumber to prevent data loss in precision

NSDecimalNumber initializers

Apple Pay within apps 144


WWDC 2015

NSDecimalNumber
NSDecimalNumber(string)
NSDecimalNumber(decimal)
NSDecimalNumber(double)

Creating the view controller

let vc = PKPaymentAuthorizationViewController(paymentRequest: request)


vc.delegate = self
presentViewController(vc, animation: true, completion: nil)

PKPaymentButton

use this button to show the view controller


support styles and colors
localization
available in iOS 8.3

Acceping a payment

requried delegate

send the payment data to processing servers and return the result in completion block

func paymentAutheroizationbViewController(controller: PKPaymentAuthorizationViewController, didAuthorizePayment payment:PKPayment, comp

Dismiss the payment view controller

func paymentAuthorizationViewControllerDidFinish( controller: PKPaymentAuthorizationViewController)

Contact information

sometimes we requires more information on the payment

paymentRequest.requiredShippingAddressFields = .PostalAddress | .Email

in iOS 8.3

paymentRequest.requiredShippingAddressFields = .Name

Shipping cost

add more charges as shipping to somewhere

as user select a new address for shipping, this delegate method is invoked. Return the shipping information by call
completion block given.

Apple Pay within apps 145


WWDC 2015

func paymentAutheroizationViewController( controller : PKPaymentAuthorizationViewController, didSelectShippingContact contact: CNContac

Creating shipping method

let twoDay = PKShippingMethod(label : "Very slow deliveary", amount: NSDecimalNumber(string: "123.33"))


twoDay.detail = "Delivers in two working days but very slow"
paymentRequest.shippingMethods = [twoDay]

once the user authorized the payment, shipping contact will be given

AddressBook API is deprecated. all related api convert to use Contact.framework in iOS 9

Tips can tricks

finding out what card did user used

if paymentMethod.type == .Debit {
// calculating surchages or discounts..
}

pending items (not yet final, refer to latest document) used for the items is not
ready or estimated

paymentSummaryItem.type = .Pending

Apple Watch

trigger iPhone to show payment sheet via hand off

check sample code

Apple Pay within apps 146


WWDC 2015

Building Responsive and Efficient Apps with GCD


Using GCD to offload some of long running tasks on different threads is one of way to keep the main thread from blocking.

QOS

any dispatch_async can assign a Quality of Service values for iOS system to optimize the schedules of threads.

QOS will be inferred.

Used if destination does not have QoS specified


Does not lower QOS and honored in all queue.

Building Responsive and Efficient Apps with GCD 147


WWDC 2015

CloudKit JS and Web services


Related Sessions : Introducing CloudKit (WWDC 2014) and Avanced CloudKit (WWDC 2014)

JSON/HTTPS interface to CloudKit


Web sign in with Apple ID
JS Library
Support browsers : Chrome, Safari, Firefox, IE , Microsoft Edge

CloudKit Architecture

Public Database
Default zone for CRUD records
Private Database
Default zone for CRUD records
Custom zone for CRUD records

Features parity as native

public/private database accesss


CRUD
Asset
Query
Subscription and notifications
User discoverability (getting users' full name)
Sync
authertication

All adove features works in JSON API

Completions block is adopted as JS promises

similar class ,methods names and calling to native counterparts.

Getting Started
1. create a container
2. create a schema
3. container can be created from either portal or xcode
4. schema can be created from CloudKit web dashboard or on-demend by the app

Enable web access


generate web service api token with cloudkit dashboard
set login callback
set domain restrictions

Lots of code sample in js to use Cloudkit

CloudKit JS and Web Services 148


WWDC 2015

Best Practices with CloudKit JS


Dynamically link to the CDN-hosted Vesion for latest release of CloudKit JS
Consider loading CloudKit JS asynchronously on your page
Handle request throttling responses (i.e. in order not to go over request/second limit, handle burst request gracefully.)

CloudKit JS and Web Services 149


WWDC 2015

CloudKit Tips and Tricks

Swiftification

Subscript

record.setObject(5, forKey:"num")
var aDate = record.objectForKey("date") as! NSDate

change into

record["num"] = 5
var aDate = record["date"]

Light generic

// [String] can not be assigned to [CKReocrd]?


modifyRecordsOperation.recordsToSave = ["I'm not a CKRecord!"]

Account Status

//check the current account status


container.accountStatusWithCompletionHandler { accountStatus, error in
...
}

Retrying Operations

CKErrorNetworkFailure

for poor network conditions

Busy Servers

CKErrorServiceUnavailable

and

CKErrorZoneBusy

look for CKErrorRetryAfterKey for time needed for retrying

CloudKit Tips and Tricks 150


WWDC 2015

Rate Limiting
CKErrorRequestRateLimited error is emitted when the quote is hit.

Handling Conflicts

CKErrorServerRecordChanged
``` for the error of conflicting records

retrieve all updated records via ```[CKRecordChangedErrorServerRecordKey``` and append newly created to the end

Suggested way for 1 to m relationships

![](clockKitOneToM.PNG)

## Batch Operation

use ```CKModifyRecordsOperation(recordsToSave: [CKRecord]?, recordIDsToDelete[CKRecordID]?)``` to submitting multiple records at once a

```CKErrorPartialFailure``` is raised if some of the records operation are not successful.

## Query

**result size limit**

// get 20 results let queryOperation= CKQueryOperation.. queryOperation.resultsLimit = 20

**dedicated keys**

let queryOperation = CKQueryOperation queryOperation.desiredKeys = ["photoThumbnail"]

**sorting**

let queryOperation = NSSortDescriptor(key : "creationDate", ascending: false) query.sortDescriptors = [byCreation]

Config field sorting via iCloud Dashboard before the records created.

**Pagination**

set ```queryCompletionBlock``` and retrieve ```CKQueryCursor``` for reminding results

## Local cache

using private database for personal data

``` let customZone = CKReocrdZone(zoneName: "custom")

use CKQueryOperation to query


Delta downloads using CKFetchRecordChangesOperation
Custom zone with CKRecordZoneCapabilityFetchChanges

invoke record.encodeSystemFieldsWithCoder and record.decodeSystemFieldsWithCoder to archive CKRecord and avoid

CloudKit Tips and Tricks 151


WWDC 2015

conflicts

only need to provide the fields need to change and accompanying with CKRecord

Subscriptions
notify app of any changes on

Query that satisfy


zone
User Notification

enable APS
entitlement
Registration with UIApplication
Silent Push

REmote notification background mode


handle via func application(application: UIApplication, didReceiveREmoteNotification: [NSObject: AnyObject],
fetchCompletionHandler: (UIBackgroundFetchResult) -> Void) { }

setting CKNotificationInfo.shouldSendContentAvailable = true with no alert body, should barge and soundName

retrieve collection of push with CKFetchNotificationChangesOperation and handle background task with
UIApplication.beginBackgroundTaskWithName

Interactive Notificaion
set CKNotificationInfo.category

Performance
use NSOperation dependency to manage tasks relationships for sake of readability and ease for debug

set QoS for NSOperation for let system to handle the operation and perform the tasks

CloudKit Tips and Tricks 152


WWDC 2015

Introducing Search APIs


User spends more time on apps than web

developers select what to index


app result shows in Spotlight and Safari
app result shows even the app is not installed

How Apple discover the app content


Deep Links go into Apple cloud index as well
Developer tag the content as public
Apple find deep links from the web as the web mirror the contents of app
appear in iOS 9 search

NSUserActivity
NSUserActivity used primary in Handoff which introduced in iOS 8.

In iOS 9, activities can be designed as searchable.

Steps to add into on-device index

1. Create NSUserActivity
2. Added related metadata such as the title, descriptions and thumbnails
3. Add that activity to the index

the following properties are only available in iOS 9

setting eligibleForHandoff to true that allows that activity can be continues via Hand off

setting eligibleForSearch to true that allows that activity can be as a result in Spotlight

setting keywords with keywords for helping the search

setting contentAttrivuteSet for information appearing in search result

setting expirationDate for the date of expiring any content when the content is not valid in after the expiration date.

setting webpageURL for restoration to a web page

Creating NSUserActivity

var activity: NSUserActivity = NSUserActivity(activityType:"com.myApp.myActivity")


activity.title = "activity title"
activity.userInfo = ["id": "1234"]
activity.eligibleForSearch = true
activity.becomeCurrent()

Introducing Search APIs 153


WWDC 2015

the search result

Receiving NSUserActivity ( same from search results and hand off)

func application(UIApplication, continueUserActivity userActivity: NSUserActivity, restorationHandler: [AnyObject]? -> Void) -> Bool {

//handle the activity


if userActivity.activityType == "com.myApp.myActivity" {

return true
}

Designating Activities Public

var activity: NSUserActivity = NSUserActivity(activityType:"com.myApp.myActivity")


activity.title = "activity title"
activity.userInfo = ["id": "1234"]
activity.eligibleForSearch = true
//setting the public indexing as true
activity.eligibleForPublicIndexing = true
activity.becomeCurrent()

Activities are private as default


only pulic of those activities marked as public
threshold of indexing (i.e. CloudIndex would only index the activities after a number of same user activities have been
done.)

Addditional Benefits

adopting hand off

Introducing Search APIs 154


WWDC 2015

Siri suggestion and smart reminders

CoreSpotlight
treated as database
index for all app content
create, update and delete
adopt by Message, Mail, Calendar and Notes

Steps to create

1. Create CSSearchableItemAttributeSet
2. Create CSSearcableItem
3. Add them to index

let attributeSet = CSSearchableItemAttributeSet(itemContentType: kUUTypeImage as String)

attributeSet.title = "Sunrise"
attributeSet.contentDescription = "Nice Sunrise on May 12, 2015"

//Create item with unique id, domainIdentifier for groupping up the the items
let item = CSSearchableItem(uniqueIdentifier: "1", domainIdentifier : "album-1", attributeSet: attributeSet)

CSSearchableIndex.defaultSearchableIndex().indexSearchableItems([Item]) { error in
if error != nil {
//handle error
} else {
//index success
}
}

Restoration

Introducing Search APIs 155


WWDC 2015

Same API as hand off but the type checked against is CSSearchableItemActionType

func application(UIApplication, continueUserActivity userActivity: NSUserActivity, restorationHandler: [AnyObject]? -> Void) -> Bool {

//handle the search result


if userActivity.activityType == CSSearchableItemActionType {

let uniqueIdentifier = userActivity.userInfo?[CSSearchableItemActivityIdentifier] as? String

return true
}

Update

same method as adding item to index

func indexSearchableItems(items: [CSSearchableItem], completionHandler:


((NSError?) -> Void)?)

Delete

delete items by identifiers

func deleteSearchableItemsWithIdentifiers(identifiers: [String],


completionHandler: ((NSError?) -> Void)?)

by domain identifiers

func deleteSearchableItemsWithDomainIdentifiers(domainIdentifiers: [String],


completionHandler: ((NSError?) -> Void)?)

or all

func deleteAllSearchableItemsWithCompletionHandler(completionHandler: ((NSError?) -> Void)?)

Additional features

item size can be large so the index allows batching


CSSearchableIndexDelegate for observe any indexing changes

extension
Data protection class for more security features

Web markup
As some of the website mirrors the conten of the app. Search in iOS 9 can also shows the results from those websites.

Enable app search

Introducing Search APIs 156


WWDC 2015

1. Allow Apple to discover and index the website


2. the website contains markup for mobile deeplinks
3. have deep link handling for the app
4. Add markup for structured data (not required but recommended)

Smart app banner

Showing the app banner promotion on the top of the website

Prepare the website

Related session: seamless linking to your app

Added twitter cards and Facebook App links as well

Rich results

Besides showing title and description, images or other media can also used for search results.

Rating, offer, price ranges, interaction counts, organization and recipe

Phone number, directions or playing audio or video are actionable for iOS search results.

check below for more info

Resources Link

App Search Developer Site http://developer.apple.com/ios/search/

Twitters Cards Protocol http://dev.twitter.com/cards/mobile

Facebooks App Links http://applinks.org

Introducing Search APIs 157


WWDC 2015

schema.org http://schema.org

Open Graph http://ogp.me

Relevance: Linking APIs


NSUserActivity.relatedUniqueIndentifer should same as CSSearchableItem.uniqueIdentifier

provide the most relevant results


result quality related to the user interaction
three thing contributed to relevance score
URL popularity
User Activity
Engagement (how many user tap the result)

Boosting the ranking

create great app and content


adopting API to gives most relevance
NSUserActivity
NSUserActivity public indexing as needed.
Schema markup for rating and reviews
Follow UI guideslines
when the user search a result, there should be no interruption to that result of you app
Go straign to the content , no full screen and multi-steps or requiring user login
applies to web and app as well
Time from result to content is a one of factor of ranking.

Protecting Relevance

down-rank or suppress poor results


Malicious or poorly considered implementation will be penalized
Ratio of engagement-to-shown is a key metric
Results
Rich results have thumbnails and well-organized data, ratings and actions
Relevant and appealing image
key information is user looking for
Keywords
3 - 5 words
category "tickets" or recipe" helps
Synonyms and abbreviations for item subject

What to index

content viewed, created and curated by user


Navigation points and features
New message, content and items arriving on device
proactively indexed items as potential interest
iOS Search is flexible, extensible, and open to creativity

Introducing Search APIs 158


WWDC 2015

Introduction to Watch Connectivity


From WatchOS 1, there are only limited ways to communicate between Apple Watch and iPhone. In WatchOS2 , Watch
Connectivity framework enables third-party developers to have better options to send and receive data from Watch.
Additional safe guards are provided to check if the connectivity is available and well-established.

Setup

//check if the device supports Watch Connectivity (iPhone supports but iPad does not)
if (WCSession.isSupported()) {
let session = WCSession.defaultSession()
session.delegate = self
sesssion.activateSession()
}

//WCSessionDelegate methods
//called whenever the session had changed
func sessionWatchStateDidChange(_ session: WCSession) {
//use this to check if the watch and iPhone are paired
if ( session.paired ) {
...
}

//check if the watch has installed the watch app


if ( session.watchAppInstalled ) {
...
}

//watchDirectoryURL is not nil if the watch has installed the watch app
if let session.watchDirectoryURL {
}

//check if the complication is enabled on watch face


if (session.complicationEnabled ) {
}
}

Communication

Background transfers

Content not needed immediately


OS intelligently transfers content
The message will be queue up
OS pick the opportune time for sending
Delievers when the receiver app is launched

Types

Application context
most interesting/ relvent content to deliver
Overriding behavior
In Dictionary
Not in main thread
Recommend to use in Most watch app and glance

//sending

Introduction to Watch Connectivity 159


WWDC 2015

do {
let context = // Create context dictionary with latest state
try WCSession.defaultSession().updateApplicationContext(context)
} catch {
// Handle any errors
}
//receiving
func session(session: WCSession, didReceiveApplicationContext:
applicationContext: [String : AnyObject]) {
// Handle application context dictionary
}

User Info content


information about user info like game level completions and inform iPhone or starting a location
In Dictionary
Not on main thread
on outstanding queue on sender
Cancel as nedded

//Sending
let userInfo = // Create dictionary of userInfo
//get transfer object for cancelling
let userInfoTransfer = WCSession.defaultSession().transferUserInfo(userInfo)
//Check outstanding items for transferring
let transfers = WCSession.defaultSession().outstandingUserInfoTransfers()
//Reciving
func session(session: WCSession, didReceiveUserInfo userInfo: [String : AnyObject]) {
// Handle incoming user info dictionary
}

File Transfer
Similar to user info transfer but transferring files
Provided metadata for accompanying the file URL
Must move files to app's space as the inbox of receiver will be clean up once the transfer is finsihed

//Sending
let url = // Retrieve URL of file
let metadata = // Create dictionary of metadata
let fileTransfer = WCSession.defaultSession().transferFile(url,
metadata:metadata)
//Outstanding queue
let transfers = WCSession.defaultSession().outstandingFileTransfers()
// Receiver Callback
func session(session: WCSession, didReceiveFile file: WCSessionFile) {
// Handle file URL and metadata in WCSessionFile object
}

Interactive messaging

Live communication

iPhone app in background


Watch app must be foreground
Devices are connected
use session.reachable to check if the interactive messaging is available
Types
Plist

func sendMesage(message:, replyHandler:, errorHandler:)

Introduction to Watch Connectivity 160


WWDC 2015

Data (custom data or own serialization)

func sendMessageData(data:, replyHandler:, errorHandler:)

Optional handler used for confirmation by receiver

separate delegate callbacks with/ without handler

func session(session: WCSession, didReceiveMessage message: [String :


AnyObject], replyHandler: ([String : AnyObject]) -> Void) {
// Handle message, return reply
}
func session(session: WCSession, didReceiveMessage message: [String :
AnyObject]) {
// Handle message
}

NSURLSession
requires instant / new content
Content is tailor-made to watch in terms of smaller size or more concise
Usage : Complication
fetch content via NSURLSession while WatchKit Extension in the background
Register via PushKit and set desiredPushTypes as [PKPushTypeComplication]
Upload the push token to the server
receiver push payload via didReceiveIncomingPushWithPayload to transfer timeLineEntry to the watch
session.transferCurrentComplicationUserInfo(presentTimeLineEntry) to transfer

func session(session: WCSession, didReceiveUserInfo userInfo: [String : AnyObject]) to handle the receiver and

update complication

Introduction to Watch Connectivity 161


WWDC 2015

Low Energy, High Performance: Compression and


Accelerate

New compressor
lzfse is new compressor in iOS 9 which bring faster compression and higher compression ratio to zlib. Lzfse also is more
energy-efficient than zlib

simd
2D, 3D and 4D vectors and matrices c, Objective-C and c++ and now on swift

Sparse BLAS
New on iOS 9.0 and OSX 10.11 Simple API and good performace Support single and double precision

Low Energy,High Performance:Compression and Accelerate 162


WWDC 2015

Networking with NSURLSession


Networking is one of critical features for every iOS app.In iOS 9, there are some important update for networkings and
related framework NSURLSession

App Transport Security (ATS)


Disallow cleartext HTTP URL locals
Encourage secure connections
Defaults to stronger security
Allows exception via app's info.plist

Sample info.plist for exception http protocol

More explanation and keys on ATS

ATS only active when the app is built with iOS 9 SDK for iOS 9 and OX El Capitan

Automatic convert from http:// to https://

Use NSAllowsArbitraryLoads for quick triage (allow load all http and https)

CFNETWORK_DIAGNOSTICS=1 to log all error from system networking

NSURLSession supports HTTP/2 automatically and nothing to change in code

NSURLSession on watchOS
NSURLSession availabe in watchOS 2

Best Practices

Download the minimal assets

small screen
limited bandwidth

Since the apps run very short time

send small amounts of data

Networking with NSURLSession 163


WWDC 2015

use background upload and downloads for larger content

NSURLConnection is deprecated in OS 10.11 and iOS 9.0

existing apps using it will still work


New features only available in NSURLSession
Not supported on watchOS

New features on NSURLSession

shared cookies storage


NSURLSessionStreamTask

supports TCP/IP connections with hostnames and ports


NSURLSession configuration and session delegates applies

support TLS
convertion from NSStream

Networking with NSURLSession 164


WWDC 2015

Privacy And Your App


This sessions talks about the goal and measure of Apple and new privacy update for iOS 9.

Update
In iOS 9, the developer must add these info.plist

<key>LSApplicationQueriesSchemes</key>
<array>
<string>urlscheme</string>
<string>urlscheme2</string>
<string>urlscheme3</string>
<string>urlscheme4</string>
</array>

to show the intent for calling external apps if the app call canOpenUrl for these urlSchemes

If a url scheme is declared and calling canOpenURL(scheme)

YES if a installed app supports that URL scheme

NO if no app supporting that url

syslog will show capOpenURL: failed for URL: "urlScheme://" - error: null

If a url scheme is not declared and calling canOpenURL(scheme)

always return NO

syslog will show capOpenURL: failed for URL: "urlScheme://" - error: null

50 max. unqiue URL scheme can be declared!

Unverisal Links -> Seamless linking to your app

low level functions


sysctl() will not allowed

Safari Content Blocker (new extension)


Blocks list for safari and safari view controller UIWebView is not affected

OS X
Cookies not shared and in sepearated process in El Captian

WatchOS

Privacy And Your App 165


WWDC 2015

Privacy setting are shared between paired devices(Watch and Phone) Privacy setting across all extensions

Keychain is available on watchOS 2

Idenitifers:

Name
Phone number
Randomly generated number
UUID

Identifier for developers

Privacy And Your App 166


WWDC 2015

WatchOS 2 requires developer to maintain the Vendor ID and Advertising ID.

Best Practices

1. Determine if an identifier is needed


2. If you need an identifier, properly scope it
3. Use OS provided identifiers
4. Ensure the usage follows the guideline
5. Always check the value of Limit Ad tracking and the advestingIdentifier before use it
i. let identifierAdvertising = ASIdentifierManager,shareManager().advestingIdentifier.UUIDString
6. never cache as user can reset the identifier

Protect User Data


NSURLErrorAppTransportSecurityRequiresSecureConnection will throw if there is an insecure connections

add exception in info.plist


Related Session : Networking with NSURLSession
Loyalty Passes
Related Session :Wallet - The home for Aplle pay and more
Deep App Search

NSUserActivity

all apps
Extension of iOS 8 handoff app

Privacy And Your App 167


WWDC 2015

setting these properties for searching


eligibleForHandoff

eligibleForSearch

eligibleForPublicIndexing

expirationDate

all default off


if threshold exceeds , the data can be search publicly
CoreSpotlight for protect files for searching
func indexSearchableItem for updating index

func deleteSearchItemWithIdentifiers for delete from index

func deleteSearchItemsWithDomainIdentifiers for delete from index

func deleteSearchItemWithCompletionHandler for delete from index

Related Session : introducing app search

Existing Technologies for protect user data


Touch ID
Apple Pay
Privacy Policy transparence
iTunes Privacy Policy URL
Data protection
hardware encryption
per file encryption

Privacy And Your App 168


WWDC 2015

Security and Your Apps


This session focuses on the security of Apple provided in OS X and iOS.

App Transport Security


Apps build against with iOS 9 and OSX 11 cannot make HTTP connections. Add exceptions on info.plists for each insecure
domain.

System Integrity Protection


Multi-layered protections for OSX.

OSX 11 will move all third-party binary to user-space from system locations.

The Keychain and Touch ID

Keychain

specialized databases
optimized for searching attributes
efficiently storing for small payload

Consideration

turn keychain code into a sample and testable unit


User the highest data protection level
Default kSecAttrAccessibleWhenUnlocked
Background apps kSecAttrAccessibleAfterFirstUnlock
Deprecated kSecAttrAccessibleAlways

Reducing Password Prompts

Web and native app shared web credentials


Add App entitlement Associated Domains for actual devices
webcredentials:www.example.com
Server JSON (https://example.com/apple-app-site-association)

//sample json:
{
"webcredentials":
{
"apps": [
"YWBN8XTPBJ.com.example.app",
"YWBN8XTPBJ.com.example.app-dev"
]
}
}

//saving to shared container


let user = "a@a.com"

Security and Your Apps 169


WWDC 2015

let password = SecCreteSharedWebCredentialPassword().takeRetainedValue()


SecAddSharedWebCredential("www.example.com", username, passwoed) { error in print(error) }
//Retrieving from safari
SecRequestSharedWebCredential("www.macosforge.org", .None)
{ credentials, error in
if CFArrayGetCount(credentials) > 0 {
let dict = unsafeBitCast(CFArrayGetValueAtIndex(credentials, 0),
CFDictionaryRef.self) as Dictionary
let username = dict[kSecAttrAccount as String]
let password = dict[kSecSharedPassword as String]
login(username, password)
}
}

iCloud Keychain
For all passwords that can be used on multiple devices
Add kSecAttrSynchronizable to all SecItem calls
Warning
Updating or deleting items will affect items on ALL devices
Check SecItem.h
Check iOS security whitepaper

Device Specific Credentials


Examples

Limited use tokens and cookies


Encrypted messaging keys
Keys with specific protection requirements

Use Touch ID when :

Replace existing security barrier


Adding one when it would have been too inconvenient before
Examples
Viewing especially sensitive data
Confirming an operation

Security and Your Apps 170


WWDC 2015

Touch ID and Multi Factor Authentication

Security and Your Apps 171


WWDC 2015

What's new in CloudKit

CloudKit Architecture
Private Database will be count towards user's iCloud Storage

User's private data


iCloud Photo Library
User's Storage

Public Data will be count towards developers' CloudKit quota

Application public data


News
Developer's storage

New CloudKit Dashboard feature


usage - shows past and forcast usage of users and requests per second

CloudKit Web Service


Let web works act extensions of iOS and OS X app

Full Cloud API via JSON/ HTTPS


CloudKit JS Library made by Apple
Use Apple ID as web sign in

public database usage is the same for iOS, OSX and web

requests quota includes web, iOS and OSX .

Requires a comparable application on iOS or OSX

Whats New in CloudKit 172


WWDC 2015

What's New in Core Location


Many apps requires user's location to perform the required features or enhance the user experiences. Every year of
WWDC provides better funtionailty for developers to access and provides more control for the users to handle app-wise
locational permissions.

authorization
location updates
indoor updates
more accurate
faster detection
region monitoring
iBeacon
Geographic
Visit monitoring
Sig. Location change/ Geocoding/ Reverse-Geocoding

Background location
iOS 4+ background mode
Add UIBackgroundModes
iOS 9 simplifty the workflow
Lower stake
Loose coupling
allowsBackgroundLocationUpdates property per CLLocationManager

Default values: NO
when finish : set it to NO And not tracking the location
MUST UPDATE FOR IOS 9
check with -responsdToSelector:
Audible cue? Related session: What's new in core audio
Single location
requestLocation by giving desiredAccuracy to locationManager .

Automatically (so you dont need to monitor start/stop by yourself, system handled for you)
start (exculsive only one at a time)
threholds internally
calls delegate once locationManager:didUpdateLocations: or locationManager:didFailWithError
stop

// from : http://nshipster.com/ios9/
class ViewController : UIViewController, CLLocationManagerDelegate {
let locationManager = CLLocationManager()
// ...

override func viewDidLoad() {


super.viewDidLoad()

locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
locationManager.requestLocation()
}

// MARK: - CLLocationManagerDelegate

func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {


if let location = locations.first {
print("Current location: \(location)")
} else {
// ...

What's New in Core Location 173


WWDC 2015

}
}

func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {


print("Error finding location: \(error.localizedDescription)")
}
}

Authorization
Apple Watch: Best practices
Authorization applies to both Watch and iPhone
requestWhenInUserAuthorization

requestAlwaysAutherization

iOS WhenInUse Always

Location YES YES

Background(continuous) YES YES

Background(intermittent) NO YES

Monitor Local notifiation YES

watchOS WhenInUse Always

Location Single Single

Background(continuous) NO NO

Background(intermittent) NO Single

Monitor NO NO

location in use if
blue bar
foreground
handling message from apple watch

Accuracy with iPhone

requestLocation Even indoor

Accuracy without iPhone

requestLocation kCLLocationAccurayHundredMeters

Best effort

Cooperation
if the app need:
continuous background monitoring
Region Monitoring
Anything availabe on iOS but not allowed on watchOS
User WCSession Related session : Introducing Watch Connectivity
sendMessage:replyHandler:errorHanlder: (watch to phone)

remember set allowsBackgroundLocationUpdates yes to get location


updateApplicationContent: (iPhone to Apple Watch)

Last one kept until the watch app is running


-allowDeferredLocationUpdateUntilTraveled:timeout: use this latency to update location based on

What's New in Core Location 174


WWDC 2015

distance traveled or time passed.

What's New in Core Location 175


WWDC 2015

What's new in Core Motion


Core Moiton API is mostly available in WatchOS2

And the states of watch can track

What's new in Core Motion 176


WWDC 2015

Apple Watch Accelerometer


Available through CMAccelerometer

Challenges

Limited processing time


Screen may turn off due to user motion (so no accelerotion data)

Best practices

Expect the data only the app is activiate


Prepare when the task can be suspended

Use performExpiringActivityWithReason(_:, usingBlock:) when being informed the task is being suspended

Historical Accelerometer
collect contiuous data for long durations
Can retrieve even the app is not running
Using the data for custom data analysis

CMSensorRecorder available in iOS 9

init the CMSensorRecorder to start the recording


recording at 50Hz
data stored up to 3 days

accelerometerDataFrom(_:, to:) -> CMSensorDataList to retrieve the data from a date to a date

What's new in Core Motion 177


WWDC 2015

Consideration of using

as the data set could be very large, the time of running can be long and again use
performExpiringActivityWithReason(_:, usingBlock:) to monitor if the task is suspended.

consume power

Best practices

Record and query minimum duration


understand sensor rate requirements
Decimate data to reduce processing time ( say if we need past record of user's running, we just retrieve past 1 to 2
hours is more than enough)

Related session : Introducing WatchKit for watchOS 2

Pedometer
Measure

1. step
2. distance
3. floor counting

New in iOS 9

Pace

New property currentPace of CMPedometerData

instantaneous pace in unit of second/meter accompanied with live pedometer updates

Cadence

Wikipedia of Cadence)

Cadence in sports involving running is the total number of 'revolutions per minute' (RPM), or number of full cycles taken
within a minute, by the pair of feet, and is used as a measure of athletic performance.

New property cadence of CMPedometerData

Availability in devices

What's new in Core Motion 178


WWDC 2015

Pressure
Used to measure relative altitude in floor-scale

not useful when :


Weather changes over long duration (as air pressure changes over time as temp.)
Rigid sealed cases

use CMAltimeter of startRelativeAltitudeUpdatesToQueue(_:, withHandler:)

first sample after 2.6s

after than the samples after 1.3s

Using core motion to enhance app experience


considering using core motion to improve UX of the app

say in music app

we detect the user activity and select the pre-defined playlists. Then according to performace of user activities , the app
changes the songs for cheering the user up. Finally we consolidate the data and shows these to the user.

What's new in Core Motion 179


WWDC 2015

What's new in network extension and VPN

Use cases
auto-connect wifi hotspots
Personal VPN provider
Enterprise Remote Access
School Filtering

NEHotspotHelper

helps to identify available wifi hotspots and the developers provide confident level for hotspots. Acts as a helper to perform
initial authentication and and maintain the authentication session.

NEVPNManager

create a personal VPN configuration


IKEv1 and IKEv2 are supported
Configure Connect On Demand
Configure HTTP proxies
Works with enterrpise VPN configs

NETunnelProviderManager and NSAppProxyProviderManager

custom VPN protocol provider


runs as an app extension
Packet Tunnel Provider for IP layer tunneling
App Proxy Provider for app layer tunneling
Config and control the providers from the app

per-app VPN for manager apps

Config per-app VPN using MDM


enroll device in MDM
Link Managed apps with per-VPN configs
Supported Protocols
Custom App Proxy Provider
Custom Packet Tunnel Providers
built-in IPSec (IKEv1 and IKEv2)

NEFilterProvider

on-device filtering
able to update the filtering rules from the internet
customizable block page
app uses webkit that the data will pass though
app is not using webkit, the data will pass though from the socket

What's new in Network extension and VPN 180


WWDC 2015

Using Network Extension APIs


for NEVPNManager for development by selecting the "personal VPN" capability in Xcode

Special entitlements for NEHotspotHelper , NETunnelProviderManager and NEFilterProvider and send request at
networkextension@apple.com

What's new in Network extension and VPN 181


WWDC 2015

What's New in Notifications


Notifications are essential part for iOS. In iOS 9, notifications are allowed to do "reply".

iOS Notification

Slient Notification
notify the app
dont need user's approve
background app refresh (beware if user turn off)
Best effort( not 100%!)
User Notification
notify user
requires user permissions
Can be disabled
Local Notification sent by
Time
Location
Remote Notification
Actions (Interactive Notifications)
Categories
Everything supported in WatchOS2
Custom look of notifications
Related Session: WatchKit In-Depth, Path 1 & WatchKit In-Depth, Path 2
Text input
New Actions
Everywhere
Work with Multiple actions

//Registering the text input notification


let replyAction = UIMutableUserNotificationAction()
reply.title = "reply"
//config rest of actions..
reply.behavior = .TextInput
//Receive the text input
protocol UIApplicationDelegate {
func application(application: UIApplication,
handleActionWithIdentifier identifier: String?,
forRemoteNotification notification: [ NSObject : AnyObject ],
withResponseInfo responseInfo: [ NSObject : AnyObject ],
completionHandler completionHandler: () -> Void)
{
//Handle responseInfoDict with text input in notification
if identifier == "comment-reply",
let response = responseInfo[UIUserNotificationActionResponseTypedTextKey],
responseText = response as? String {
viewController.appendText(responseText)
}
completionHandler()
}

For more in Apple Watch, Related Session: WatchKit In-Depth, Path 1 & WatchKit In-Depth, Path 2

Text input

iOS 8 Competibility

What's New in Notifications 182


WWDC 2015

Register different notification actions for different ios version (iOS 8 does not have text input)

Updates in APNS
APNS Feedback Push provider pulls data periodically to validate the tokens

Large Push token from 32 bit to 64 bit

New Provider API

the connection between APNS and Providers are in HTTP/2 protocol

Instant Feedback no need to pulling from Feedback to provider APNS will tell provider if the device token is invalid and the
timestamp of that start invalided.

Simple Certificate handling

applications push
VOIP push
Watch Complication push
Development and production environments
NOW ON ONE CERTIFICATE

Push payload from 2KB to 4KB applying all iOS version and OSX

Related Session: Creating Complication with ClockKit, Networking with NSURLSession, Introducting Watch Connectivity

What's New in Notifications 183

Вам также может понравиться