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)
// 👍
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

## 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