244
© 2015 Apple Inc. All rights reserved. Redistribution or public display not permitted without written permission from Apple. #WWDC15 App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224

App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

  • Upload
    others

  • View
    8

  • Download
    0

Embed Size (px)

Citation preview

Page 1: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

© 2015 Apple Inc. All rights reserved. Redistribution or public display not permitted without written permission from Apple.

#WWDC15

App Extension Best Practices

Sophia Teutschler UIKit EngineerIan Baird CoreOS Engineer

App Frameworks

Session 224

Page 2: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Agenda

Page 3: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Agenda

Action and Share Extensions

Page 4: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Agenda

Action and Share ExtensionsToday widget enhancements

Page 5: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Agenda

Action and Share ExtensionsToday widget enhancementsReal world examples

Page 6: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share Extensions

Page 7: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share Extensions

ShareAction

Page 8: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsAction Extensions

Action

Page 9: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsAction Extensions

Acts on the current content

Action

Page 10: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsAction Extensions

Acts on the current contentUses the content as the user interface

Action

Page 11: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsAction Extensions

Acts on the current contentUses the content as the user interfaceOpportunity to present additional options

Action

Page 12: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsAction Extensions

Acts on the current contentUses the content as the user interfaceOpportunity to present additional optionsApp can provide multiple Action Extensions

Action

Page 13: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action
Page 14: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Page 15: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

⇄⇄

Page 16: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

⇄⇄

Page 17: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action
Page 18: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action
Page 19: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action
Page 20: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share Extensions

ShareAction

Page 21: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share Extensions

Share

Page 22: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsShare Extensions

Share

Page 23: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsShare Extensions

Shares content to your app or web service

Share

Page 24: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsShare Extensions

Shares content to your app or web serviceAllows validation and editing

Share

Page 25: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsShare Extensions

Shares content to your app or web serviceAllows validation and editingCan use SLComposeServiceViewController

Share

Page 26: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsShare Extensions

Shares content to your app or web serviceAllows validation and editingCan use SLComposeServiceViewControllerYour app provides one Share Extension

Share

Page 27: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action
Page 28: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action
Page 29: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action
Page 30: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action
Page 31: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action
Page 32: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsSLComposeServiceViewController

Page 33: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsSLComposeServiceViewController

Page 34: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsSLComposeServiceViewController

viewController.placeholder = "Caption (Optional)"

Page 35: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsSLComposeServiceViewController

viewController.placeholder = "Caption (Optional)"

Page 36: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsSLComposeServiceViewController

viewController.charactersRemaining = 80

Page 37: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsSLComposeServiceViewController

viewController.charactersRemaining = 80

Page 38: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

override func loadPreviewView() -> UIView! { return FaceDetectingPreviewView(…) }

Action and Share ExtensionsSLComposeServiceViewController

Page 39: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

override func loadPreviewView() -> UIView! { return FaceDetectingPreviewView(…) }

Action and Share ExtensionsSLComposeServiceViewController

Page 40: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsSLComposeServiceViewController

func configurationItems() -> [SLComposeSheetConfigurationItem]

Page 41: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsSLComposeServiceViewController

func configurationItems() -> [SLComposeSheetConfigurationItem]

Page 42: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsSLComposeServiceViewController

override func configurationItems() -> [AnyObject]! { let item = SLComposeSheetConfigurationItem()

item.title = "Blog" item.value = "My Road Trips"

item.tapHandler = { let viewController = BlogPickerViewController() self.pushConfigurationViewController(viewController) }

return [ item ] }

Page 43: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsSLComposeServiceViewController

override func configurationItems() -> [AnyObject]! { let item = SLComposeSheetConfigurationItem()

item.title = "Blog" item.value = "My Road Trips"

item.tapHandler = { let viewController = BlogPickerViewController() self.pushConfigurationViewController(viewController) }

return [ item ] }

Page 44: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsSLComposeServiceViewController

override func configurationItems() -> [AnyObject]! { let item = SLComposeSheetConfigurationItem()

item.title = "Blog" item.value = "My Road Trips"

item.tapHandler = { let viewController = BlogPickerViewController() self.pushConfigurationViewController(viewController) }

return [ item ] }

Page 45: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsSLComposeServiceViewController

override func configurationItems() -> [AnyObject]! { let item = SLComposeSheetConfigurationItem()

item.title = "Blog" item.value = "My Road Trips"

item.tapHandler = { let viewController = BlogPickerViewController() self.pushConfigurationViewController(viewController) }

return [ item ] }

Page 46: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsSLComposeServiceViewController

override func configurationItems() -> [AnyObject]! { let item = SLComposeSheetConfigurationItem()

item.title = "Blog" item.value = "My Road Trips"

item.tapHandler = { let viewController = BlogPickerViewController() self.pushConfigurationViewController(viewController) }

return [ item ] }

Page 47: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsSLComposeServiceViewController

override func configurationItems() -> [AnyObject]! { let item = SLComposeSheetConfigurationItem()

item.title = "Blog" item.value = "My Road Trips"

item.tapHandler = { let viewController = BlogPickerViewController() self.pushConfigurationViewController(viewController) }

return [ item ] }

Page 48: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsSLComposeServiceViewController

override func configurationItems() -> [AnyObject]! { let item = SLComposeSheetConfigurationItem()

item.title = "Blog" item.value = "My Road Trips"

item.tapHandler = { let viewController = BlogPickerViewController() self.pushConfigurationViewController(viewController) }

return [ item ] }

Page 49: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsSLComposeServiceViewController

override func configurationItems() -> [AnyObject]! { let item = SLComposeSheetConfigurationItem()

item.title = "Blog" item.value = "My Road Trips"

item.tapHandler = { let viewController = BlogPickerViewController() self.pushConfigurationViewController(viewController) }

return [ item ] }

Page 50: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsSLComposeServiceViewController

override func configurationItems() -> [AnyObject]! { let item = SLComposeSheetConfigurationItem()

item.title = "Blog" item.value = "My Road Trips"

item.tapHandler = { let viewController = BlogPickerViewController() self.pushConfigurationViewController(viewController) }

return [ item ] }

Page 51: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsSLComposeServiceViewController

viewController.autocompletionViewController = SuggestionViewController(…)

Page 52: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsSLComposeServiceViewController

viewController.autocompletionViewController = SuggestionViewController(…)

Page 53: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsSLComposeServiceViewController

Page 54: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsSLComposeServiceViewController

Provides consistent and familiar UI

Page 55: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsSLComposeServiceViewController

Provides consistent and familiar UICustomizable

Page 56: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsSLComposeServiceViewController

Provides consistent and familiar UICustomizableCompletely custom UI using UIViewController

Page 57: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action
Page 58: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsBeing a good host

kUTTypePlainText

Page 59: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsBeing a good host

kUTTypePDF

Page 60: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsBeing a good host

kUTTypeHTML

Page 61: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsBeing a good host

Page 62: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsBeing a good host

kUTTypeHTMLkUTTypePDFkUTTypePlainText

Page 63: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

NSItemProvider

Action and Share ExtensionsBeing a good host

kUTTypePlainText kUTTypePDF kUTTypeHTML

Page 64: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsBeing a good host

let itemProvider = NSItemProvider()

itemProvider.registerItemForTypeIdentifier(kUTTypePlainText as String) { completionHandler, expectedClass, options in completionHandler(self.renderPlainTextDocumentString(), nil) }

itemProvider.registerItemForTypeIdentifier(kUTTypePDF as String) { completionHandler, expectedClass, options in completionHandler(self.renderPDFDocument(), nil) }

let vc = UIActivityViewController(activityItems: [ itemProvider ], applicationActivities: nil) self.presentViewController(vc, animated: true, completion: nil)

Page 65: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsBeing a good host

let itemProvider = NSItemProvider()

itemProvider.registerItemForTypeIdentifier(kUTTypePlainText as String) { completionHandler, expectedClass, options in completionHandler(self.renderPlainTextDocumentString(), nil) }

itemProvider.registerItemForTypeIdentifier(kUTTypePDF as String) { completionHandler, expectedClass, options in completionHandler(self.renderPDFDocument(), nil) }

let vc = UIActivityViewController(activityItems: [ itemProvider ], applicationActivities: nil) self.presentViewController(vc, animated: true, completion: nil)

Page 66: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsBeing a good host

let itemProvider = NSItemProvider()

itemProvider.registerItemForTypeIdentifier(kUTTypePlainText as String) { completionHandler, expectedClass, options in completionHandler(self.renderPlainTextDocumentString(), nil) }

itemProvider.registerItemForTypeIdentifier(kUTTypePDF as String) { completionHandler, expectedClass, options in completionHandler(self.renderPDFDocument(), nil) }

let vc = UIActivityViewController(activityItems: [ itemProvider ], applicationActivities: nil) self.presentViewController(vc, animated: true, completion: nil)

Page 67: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsBeing a good host

let itemProvider = NSItemProvider()

itemProvider.registerItemForTypeIdentifier(kUTTypePlainText as String) { completionHandler, expectedClass, options in completionHandler(self.renderPlainTextDocumentString(), nil) }

itemProvider.registerItemForTypeIdentifier(kUTTypePDF as String) { completionHandler, expectedClass, options in completionHandler(self.renderPDFDocument(), nil) }

let vc = UIActivityViewController(activityItems: [ itemProvider ], applicationActivities: nil) self.presentViewController(vc, animated: true, completion: nil)

Page 68: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsBeing a good host

let itemProvider = NSItemProvider()

itemProvider.registerItemForTypeIdentifier(kUTTypePlainText as String) { completionHandler, expectedClass, options in completionHandler(self.renderPlainTextDocumentString(), nil) }

itemProvider.registerItemForTypeIdentifier(kUTTypePDF as String) { completionHandler, expectedClass, options in completionHandler(self.renderPDFDocument(), nil) }

let vc = UIActivityViewController(activityItems: [ itemProvider ], applicationActivities: nil) self.presentViewController(vc, animated: true, completion: nil)

Page 69: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsBeing a good host

let itemProvider = NSItemProvider()

itemProvider.registerItemForTypeIdentifier(kUTTypePlainText as String) { completionHandler, expectedClass, options in completionHandler(self.renderPlainTextDocumentString(), nil) }

itemProvider.registerItemForTypeIdentifier(kUTTypePDF as String) { completionHandler, expectedClass, options in completionHandler(self.renderPDFDocument(), nil) }

let vc = UIActivityViewController(activityItems: [ itemProvider ], applicationActivities: nil) self.presentViewController(vc, animated: true, completion: nil)

Page 70: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsBeing a good host

let itemProvider = NSItemProvider()

itemProvider.registerItemForTypeIdentifier(kUTTypePlainText as String) { completionHandler, expectedClass, options in completionHandler(self.renderPlainTextDocumentString(), nil) }

itemProvider.registerItemForTypeIdentifier(kUTTypePDF as String) { completionHandler, expectedClass, options in completionHandler(self.renderPDFDocument(), nil) }

let vc = UIActivityViewController(activityItems: [ itemProvider ], applicationActivities: nil) self.presentViewController(vc, animated: true, completion: nil)

Page 71: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsBeing a good host

let itemProvider = NSItemProvider()

itemProvider.registerItemForTypeIdentifier(kUTTypePlainText as String) { completionHandler, expectedClass, options in completionHandler(self.renderPlainTextDocumentString(), nil) }

itemProvider.registerItemForTypeIdentifier(kUTTypePDF as String) { completionHandler, expectedClass, options in completionHandler(self.renderPDFDocument(), nil) }

let vc = UIActivityViewController(activityItems: [ itemProvider ], applicationActivities: nil) self.presentViewController(vc, animated: true, completion: nil)

Page 72: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsBeing a good host

let itemProvider = NSItemProvider()

itemProvider.registerItemForTypeIdentifier(kUTTypePlainText as String) { completionHandler, expectedClass, options in completionHandler(self.renderPlainTextDocumentString(), nil) }

itemProvider.registerItemForTypeIdentifier(kUTTypePDF as String) { completionHandler, expectedClass, options in completionHandler(self.renderPDFDocument(), nil) }

let vc = UIActivityViewController(activityItems: [ itemProvider ], applicationActivities: nil) self.presentViewController(vc, animated: true, completion: nil)

Page 73: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsBeing a good host

let itemProvider = NSItemProvider()

itemProvider.registerItemForTypeIdentifier(kUTTypePlainText as String) { completionHandler, expectedClass, options in completionHandler(self.renderPlainTextDocumentString(), nil) }

itemProvider.registerItemForTypeIdentifier(kUTTypePDF as String) { completionHandler, expectedClass, options in completionHandler(self.renderPDFDocument(), nil) }

let vc = UIActivityViewController(activityItems: [ itemProvider ], applicationActivities: nil) self.presentViewController(vc, animated: true, completion: nil)

Page 74: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsBeing a good host

Page 75: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsBeing a good host

Host apps should offer content previews

Page 76: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsBeing a good host

Host apps should offer content previews• Represents what will be shared

Page 77: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsBeing a good host

Host apps should offer content previews• Represents what will be shared• Simple and efficient representation of the content

Page 78: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsBeing a good host

itemProvider.previewImageHandler = { completionHandler, expectedClass, options in completionHandler(self.renderThumbnail(), nil) }

Page 79: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsBeing a good host

itemProvider.previewImageHandler = { completionHandler, expectedClass, options in completionHandler(self.renderThumbnail(), nil) }

Page 80: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsBeing a good host

itemProvider.previewImageHandler = { completionHandler, expectedClass, options in completionHandler(self.renderThumbnail(), nil) }

Page 81: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsBeing a good host

itemProvider.previewImageHandler = { completionHandler, expectedClass, options in completionHandler(self.renderThumbnail(), nil) }

Page 82: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsActivation rules

Page 83: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsActivation rules

Host App

kUTTypeMovie

kUTTypeImage

Page 84: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsActivation rules

NSExtensionActivationSupportsImage

NSExtensionActivationSupportsMovie

NSExtensionActivationSupportsImage

NSExtensionActivationSupportsMovie

Extension

Extension

Extension

Host App

kUTTypeMovie

kUTTypeImage

Page 85: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsActivation rules

Host App

kUTTypeMovie

kUTTypeImage

NSExtensionActivationSupportsImage

NSExtensionActivationSupportsMovie

NSExtensionActivationSupportsImage

NSExtensionActivationSupportsMovie

Extension

Extension

Extension

Page 86: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsActivation rules

Host App

kUTTypeMovie

kUTTypeImage

NSExtensionActivationSupportsImage

NSExtensionActivationSupportsMovie

NSExtensionActivationSupportsImage

NSExtensionActivationSupportsMovie

Extension

Extension

Extension

Page 87: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsActivation rules

NSExtensionActivationSupportsImage

NSExtensionActivationSupportsMovie

NSExtensionActivationSupportsImage

NSExtensionActivationSupportsMovie

Extension

Extension

Extension

Host App

kUTTypeMovie

kUTTypeImage

Page 88: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsActivation rules

Page 89: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsActivation rules

Page 90: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsActivation rules

Page 91: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsActivation rules

NSExtensionActivationSupportsImage

NSExtensionActivationSupportsMovie

NSExtensionActivationSupportsImage

NSExtensionActivationSupportsMovie

Extension

Extension

Extension

Host App

kUTTypeMovie

kUTTypeImage

Page 92: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsActivation rules

SUBQUERY(extensionItems, $extensionItem, SUBQUERY($extensionItem.attachments, $attachment, ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.image").@count == 1).@count == 1 OR SUBQUERY(extensionItems, $extensionItem, SUBQUERY($extensionItem.attachments, $attachment, ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "com.adobe.pdf").@count == 1).@count == 1

Page 93: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsActivation rules

SUBQUERY(extensionItems, $extensionItem, SUBQUERY($extensionItem.attachments, $attachment, ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "public.image").@count == 1).@count == 1 OR SUBQUERY(extensionItems, $extensionItem, SUBQUERY($extensionItem.attachments, $attachment, ANY $attachment.registeredTypeIdentifiers UTI-CONFORMS-TO "com.adobe.pdf").@count == 1).@count == 1

Page 94: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsIcons

Page 95: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsIcons

Share Extensions use the containing app icon

Page 96: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsIcons

Share Extensions use the containing app icon• No additional work needed

Page 97: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsIcons

Page 98: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsIcons

Action Extensions require template images

Page 99: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsIcons

Action Extensions require template images• Two sizes for iPhone and iPad

Page 100: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsIcons

Action Extensions require template images• Two sizes for iPhone and iPad• Reside in the extension bundle

Page 101: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsIcons

Page 102: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsAction icons

Page 103: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsAction icons

76pt60pt

⇄⇄

Page 104: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Action and Share ExtensionsAction icons

76pt60pt29pt 40pt

⇄⇄⇄⇄

Page 105: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Today Widget Enhancements

Ian Baird CoreOS Engineer

Page 106: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Today Widget Enhancements

Quick information at a glance

Page 107: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Today Widget Enhancements

Quick information at a glanceEnhance your Today widget

Page 108: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Today Widget Enhancements

Quick information at a glanceEnhance your Today widgetGeneral best practices

Page 109: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action
Page 110: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action
Page 111: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action
Page 112: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action
Page 113: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Working with the Containing AppURL handlers

Interactions use URLs to take user to app

Page 114: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Working with the Containing AppURL handlers

Interactions use URLs to take user to appBest practices

Page 115: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Working with the Containing AppURL handlers

Interactions use URLs to take user to appBest practices• Use your app’s registered URL schemes

Page 116: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Working with the Containing AppURL handlers

Interactions use URLs to take user to appBest practices• Use your app’s registered URL schemes• System URL schemes

Page 117: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Working with the Containing AppURL handlers

Interactions use URLs to take user to app.Best practices• Use your app’s registered URL schemes• System URL schemes

func tableView(…, didSelectRowAtIndexPath indexPath: NSIndexPath) { let selectedName = names[indexPath.row] let URL = NSURL(string: "my-app://name=\(selectedName)")! extensionContext!.openURL(URL) { success in print("openURL returned: \(success)") } }

Page 118: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Working with the Containing AppURL handlers

Interactions use URLs to take user to app.Best practices• Use your app’s registered URL schemes• System URL schemes

func tableView(…, didSelectRowAtIndexPath indexPath: NSIndexPath) { let selectedName = names[indexPath.row] let URL = NSURL(string: "my-app://name=\(selectedName)")! extensionContext!.openURL(URL) { success in print("openURL returned: \(success)") } }

Page 119: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Working with the Containing AppURL handlers

Interactions use URLs to take user to app.Best practices• Use your app’s registered URL schemes• System URL schemes

func tableView(…, didSelectRowAtIndexPath indexPath: NSIndexPath) { let selectedName = names[indexPath.row] let URL = NSURL(string: "my-app://name=\(selectedName)")! extensionContext!.openURL(URL) { success in print("openURL returned: \(success)") } }

Page 120: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Working with the Containing AppURL handlers

Interactions use URLs to take user to app.Best practices• Use your app’s registered URL schemes• System URL schemes

func tableView(…, didSelectRowAtIndexPath indexPath: NSIndexPath) { let selectedName = names[indexPath.row] let URL = NSURL(string: "my-app://name=\(selectedName)")! extensionContext!.openURL(URL) { success in print("openURL returned: \(success)") } }

Page 121: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Working with the Containing AppApp groups

Defaults

Page 122: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Working with the Containing AppApp groups

DefaultsContainers

Page 123: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Working with the Containing AppApp groups

DefaultsContainersKeychain items

Page 124: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Working with the Containing AppApp groups

DefaultsContainersKeychain itemsFramework data

Page 125: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Working with the Containing AppUser defaults

Page 126: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Working with the Containing AppUser defaults

Used for small pieces of configuration data

Page 127: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Working with the Containing AppUser defaults

Used for small pieces of configuration data

let defaults = NSUserDefaults.initWithSuiteName("group.com.example.my-app")

Page 128: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Working with the Containing AppWhat goes in a shared container?

Model data

Page 129: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Working with the Containing AppWhat goes in a shared container?

Model dataDocuments

Page 130: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Working with the Containing AppWhat goes in a shared container?

Model dataDocumentsMedia

Page 131: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Working with the Containing AppWorking with model data in the shared container

lazy var secureAppGroupPersistentStoreURL: NSURL = { let fm = NSFileManager.defaultManager() let directory = fm.containerURLForSecurityApplicationGroupIdentifier("group.com.example.my-app")! return directory.URLByAppendingPathComponent("myFileName.sqlite") }()

Page 132: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Working with the Containing AppWorking with model data in the shared container

lazy var secureAppGroupPersistentStoreURL: NSURL = { let fm = NSFileManager.defaultManager() let directory = fm.containerURLForSecurityApplicationGroupIdentifier("group.com.example.my-app")! return directory.URLByAppendingPathComponent("myFileName.sqlite") }()

Page 133: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Working with the Containing AppWorking with model data in the shared container

lazy var secureAppGroupPersistentStoreURL: NSURL = { let fm = NSFileManager.defaultManager() let directory = fm.containerURLForSecurityApplicationGroupIdentifier("group.com.example.my-app")! return directory.URLByAppendingPathComponent("myFileName.sqlite") }()

Page 134: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Working with the Containing AppWorking with model data in the shared container

lazy var secureAppGroupPersistentStoreURL: NSURL = { let fm = NSFileManager.defaultManager() let directory = fm.containerURLForSecurityApplicationGroupIdentifier("group.com.example.my-app")! return directory.URLByAppendingPathComponent("myFileName.sqlite") }()

Page 135: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Working with the Containing AppWorking with model data in the shared container

lazy var secureAppGroupPersistentStoreURL: NSURL = { let fm = NSFileManager.defaultManager() let directory = fm.containerURLForSecurityApplicationGroupIdentifier("group.com.example.my-app")! return directory.URLByAppendingPathComponent("myFileName.sqlite") }()

Page 136: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Working with the Containing AppWorking with model data in the shared container

lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = { let storeCoordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel) let storeURL = self.secureAppGroupPersistentStoreURL do { try storeCoordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption, true]) } catch let error as NSError { // handle error } return storeCoordinator }()

Page 137: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Working with the Containing AppWorking with model data in the shared container

lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = { let storeCoordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel) let storeURL = self.secureAppGroupPersistentStoreURL do { try storeCoordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption, true]) } catch let error as NSError { // handle error } return storeCoordinator }()

Page 138: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Working with the Containing AppWorking with model data in the shared container

lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = { let storeCoordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel) let storeURL = self.secureAppGroupPersistentStoreURL do { try storeCoordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption, true]) } catch let error as NSError { // handle error } return storeCoordinator }()

Page 139: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Working with the Containing AppWorking with model data in the shared container

lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = { let storeCoordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel) let storeURL = self.secureAppGroupPersistentStoreURL do { try storeCoordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption, true]) } catch let error as NSError { // handle error } return storeCoordinator }()

Page 140: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Working with the Containing AppWorking with model data in the shared container

lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = { let storeCoordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel) let storeURL = self.secureAppGroupPersistentStoreURL do { try storeCoordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption, true]) } catch let error as NSError { // handle error } return storeCoordinator }()

Page 141: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Working with the Containing AppWorking with model data in the shared container

lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = { let storeCoordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel) let storeURL = self.secureAppGroupPersistentStoreURL do { try storeCoordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption, true]) } catch let error as NSError { // handle error } return storeCoordinator }()

Page 142: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Working with the Containing AppWorking with model data in the shared container

lazy var managedObjectContext: NSManagedObjectContext = { let coordinator = self.persistentStoreCoordinator var managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType) managedObjectContext.persistentStoreCoordinator = coordinator return managedObjectContext }()

Page 143: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Working with the Containing AppWorking with model data in the shared container

lazy var managedObjectContext: NSManagedObjectContext = { let coordinator = self.persistentStoreCoordinator var managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType) managedObjectContext.persistentStoreCoordinator = coordinator return managedObjectContext }()

Page 144: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Working with the Containing AppWorking with model data in the shared container

lazy var managedObjectContext: NSManagedObjectContext = { let coordinator = self.persistentStoreCoordinator var managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType) managedObjectContext.persistentStoreCoordinator = coordinator return managedObjectContext }()

Page 145: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Working with the Containing AppWorking with model data in the shared container

lazy var managedObjectContext: NSManagedObjectContext = { let coordinator = self.persistentStoreCoordinator var managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType) managedObjectContext.persistentStoreCoordinator = coordinator return managedObjectContext }()

Page 146: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying ResponsiveLocking in the shared container

Page 147: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying ResponsiveLocking in the shared container

Be careful taking exclusive locks for data in the shared container

Page 148: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying ResponsiveLocking in the shared container

Be careful taking exclusive locks for data in the shared containerExtension killed if it’s suspended while holding an exclusive lock

Page 149: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying ResponsiveTask assertions

Extensions suspended when no longer in use

Page 150: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying ResponsiveTask assertions

Extensions suspended when no longer in useProtect serialization and other clean-up tasks with background task assertions

Page 151: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying ResponsiveTask assertions

let pi = NSProcessInfo.processInfo() pi.performExpiringActivityWithReason("clean-up") { expired in if (!expired) { self.serializeData() } else { self.cleanupSerializingData() } }

Page 152: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying ResponsiveTask assertions

let pi = NSProcessInfo.processInfo() pi.performExpiringActivityWithReason("clean-up") { expired in if (!expired) { self.serializeData() } else { self.cleanupSerializingData() } }

Page 153: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying ResponsiveTask assertions

let pi = NSProcessInfo.processInfo() pi.performExpiringActivityWithReason("clean-up") { expired in if (!expired) { self.serializeData() } else { self.cleanupSerializingData() } }

Page 154: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying ResponsiveTask assertions

let pi = NSProcessInfo.processInfo() pi.performExpiringActivityWithReason("clean-up") { expired in if (!expired) { self.serializeData() } else { self.cleanupSerializingData() } }

Page 155: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying ResponsiveTask assertions

let pi = NSProcessInfo.processInfo() pi.performExpiringActivityWithReason("clean-up") { expired in if (!expired) { self.serializeData() } else { self.cleanupSerializingData() } }

expired == false

Page 156: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying ResponsiveTask assertions

let pi = NSProcessInfo.processInfo() pi.performExpiringActivityWithReason("clean-up") { expired in if (!expired) { self.serializeData() } else { self.cleanupSerializingData() } }

expired == false –> perform protected task

Page 157: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying ResponsiveTask assertions

let pi = NSProcessInfo.processInfo() pi.performExpiringActivityWithReason("clean-up") { expired in if (!expired) { self.serializeData() } else { self.cleanupSerializingData() } }

expired == true

Page 158: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying ResponsiveTask assertions

let pi = NSProcessInfo.processInfo() pi.performExpiringActivityWithReason("clean-up") { expired in if (!expired) { self.serializeData() } else { self.cleanupSerializingData() } }

expired == true -> cancel protected task

Page 159: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying ResponsiveTask assertions

let pi = NSProcessInfo.processInfo() pi.performExpiringActivityWithReason("clean-up") { expired in if (!expired) { self.serializeData() } else { self.cleanupSerializingData() } }

exit the block -> task assertion is released

Page 160: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying ResponsiveTask assertions

let pi = NSProcessInfo.processInfo() pi.performExpiringActivityWithReason("clean-up") { expired in if (!expired) { self.serializeData() } else { self.cleanupSerializingData() } }

expired == true

Page 161: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying ResponsiveTask assertions

let pi = NSProcessInfo.processInfo() pi.performExpiringActivityWithReason("clean-up") { expired in if (!expired) { self.serializeData() } else { self.cleanupSerializingData() } }

expired == true -> cancel any work and exit the block

Page 162: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying ResponsiveTask assertions

Released when your code exits the block

Page 163: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying ResponsiveTask assertions

Released when your code exits the blockRe-entrant execution of callback for expiration

Page 164: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying ResponsiveTask assertions

Released when your code exits the blockRe-entrant execution of callback for expirationTask assertions are not always available for your extension

Page 165: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying ResponsiveWorking with other queues

Task assertion scoped to callback block

Page 166: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying ResponsiveWorking with other queues

Task assertion scoped to callback blockCallback block must synchronize with protected work on other queues

Page 167: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying ResponsiveWorking with other queues

Task assertion scoped to callback blockCallback block must synchronize with protected work on other queuesExample

Page 168: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying ResponsiveWorking with other queues

Task assertion scoped to callback blockCallback block must synchronize with protected work on other queuesExample• Dispatch block to the main queue

Page 169: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying ResponsiveWorking with the main queue

let pi = NSProcessInfo.processInfo() pi.performExpiringActivityWithReason("clean-up") { expired in if (!expired) { dispatch_async(dispatch_get_main_queue(), { self.performInterruptibleWork() }) } else { self.canceled = true } }

Page 170: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying ResponsiveWorking with the main queue

let pi = NSProcessInfo.processInfo() pi.performExpiringActivityWithReason("clean-up") { expired in if (!expired) { dispatch_async(dispatch_get_main_queue(), { self.performInterruptibleWork() }) } else { self.canceled = true } }

Page 171: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying ResponsiveWorking with the main queue

let pi = NSProcessInfo.processInfo() pi.performExpiringActivityWithReason("clean-up") { expired in if (!expired) { dispatch_sync(dispatch_get_main_queue(), { self.performInterruptibleWork() }) } else { self.canceled = true } }

Page 172: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying ResponsiveWorking with the main queue

let pi = NSProcessInfo.processInfo() pi.performExpiringActivityWithReason("clean-up") { expired in if (!expired) { dispatch_sync(dispatch_get_main_queue(), { self.performInterruptibleWork() }) } else { self.canceled = true } }

Page 173: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying ResponsiveWorking with the main queue

let pi = NSProcessInfo.processInfo() pi.performExpiringActivityWithReason("clean-up") { expired in if (!expired) { dispatch_sync(dispatch_get_main_queue(), { self.performInterruptibleWork() }) } else { self.canceled = true } }

Callback block is executing on a private system queue

Page 174: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying Up to DateDarwin Notification Center

Similar to NSNotificationCenter

Page 175: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying Up to DateDarwin Notification Center

Similar to NSNotificationCenter

Page 176: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying Up to DateDarwin Notification Center

Similar to NSNotificationCenterSmall number of use-cases

Page 177: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying Up to DateDarwin Notification Center

Similar to NSNotificationCenterSmall number of use-casesExample

Page 178: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying Up to DateDarwin Notification Center

Similar to NSNotificationCenterSmall number of use-casesExample• Hint to your extension to reload the model

Page 179: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying Up to DateContaining app API

let nc = CFNotificationCenterGetDarwinNotifyCenter() CFNotificationCenterPostNotification(nc, "com.example.app-model-updated", nil, nil, CFBooleanGetValue(true))

Page 180: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying Up to DateContaining app API

let nc = CFNotificationCenterGetDarwinNotifyCenter() CFNotificationCenterPostNotification(nc, "com.example.app-model-updated", nil, nil, CFBooleanGetValue(true))

Page 181: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying Up to DateContaining app API

let nc = CFNotificationCenterGetDarwinNotifyCenter() CFNotificationCenterPostNotification(nc, "com.example.app-model-updated", nil, nil, CFBooleanGetValue(true))

Page 182: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying Up to DateContaining app API

let nc = CFNotificationCenterGetDarwinNotifyCenter() CFNotificationCenterPostNotification(nc, "com.example.app-model-updated", nil, nil, CFBooleanGetValue(true))

Page 183: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying Up to DateExtension API

let nc = CFNotificationCenterGetDarwinNotifyCenter() CFNotificationCenterAddObserver(nc, nil, { _ in self.reloadModel() }, "com.example.app-model-updated", nil, .DeliverImmediately)

Page 184: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying Up to DateExtension API

let nc = CFNotificationCenterGetDarwinNotifyCenter() CFNotificationCenterAddObserver(nc, nil, { _ in self.reloadModel() }, "com.example.app-model-updated", nil, .DeliverImmediately)

Page 185: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying Up to DateExtension API

let nc = CFNotificationCenterGetDarwinNotifyCenter() CFNotificationCenterAddObserver(nc, nil, { _ in self.reloadModel() }, "com.example.app-model-updated", nil, .DeliverImmediately)

Page 186: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying Up to DateExtension API

let nc = CFNotificationCenterGetDarwinNotifyCenter() CFNotificationCenterAddObserver(nc, nil, { _ in self.reloadModel() }, "com.example.app-model-updated", nil, .DeliverImmediately)

Page 187: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Staying Up to DateExtension API

let nc = CFNotificationCenterGetDarwinNotifyCenter() CFNotificationCenterAddObserver(nc, nil, { _ in self.reloadModel() }, "com.example.app-model-updated", nil, .DeliverImmediately)

Page 188: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Background RefreshKeeping your widget up to date

Page 189: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action
Page 190: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Background Refresh

Page 191: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Background Refresh

AAPL: $132.12

Page 192: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action
Page 193: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action
Page 194: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Background RefreshUpdating the widget

System opportunistically refreshes content

Page 195: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Background RefreshUpdating the widget

System opportunistically refreshes contentView controller conforms to NCWidgetProviding

Page 196: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Background RefreshUpdating the widget

System opportunistically refreshes contentView controller conforms to NCWidgetProvidingImplements update delegate method

Page 197: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Background RefreshUpdating the widget

System opportunistically refreshes contentView controller conforms to NCWidgetProvidingImplements update delegate method

func widgetPerformUpdateWithCompletionHandler(completionHandler: ((NCUpdateResult) -> Void)) { let updated = refreshTheModel() if (updated) { view.setNeedsDisplay() } completionHandler(updated ? .NewData : .NoData) }

Page 198: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Background RefreshUpdating the widget

System opportunistically refreshes contentView controller conforms to NCWidgetProvidingImplements update delegate method

func widgetPerformUpdateWithCompletionHandler(completionHandler: ((NCUpdateResult) -> Void)) { let updated = refreshTheModel() if (updated) { view.setNeedsDisplay() } completionHandler(updated ? .NewData : .NoData) }

Page 199: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Background RefreshUpdating the widget

func widgetPerformUpdateWithCompletionHandler(completionHandler: ((NCUpdateResult) -> Void)) { let updated = refreshTheModel() if (updated) { view.setNeedsDisplay() } completionHandler(updated ? .NewData : .NoData) }

System opportunistically refreshes contentView controller conforms to NCWidgetProvidingImplements update delegate method

Page 200: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Background RefreshUpdating the widget

func widgetPerformUpdateWithCompletionHandler(completionHandler: ((NCUpdateResult) -> Void)) { let updated = refreshTheModel() if (updated) { view.setNeedsDisplay() } completionHandler(updated ? .NewData : .NoData) }

System opportunistically refreshes contentView controller conforms to NCWidgetProvidingImplements update delegate method

Page 201: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Background RefreshUpdating the widget

func widgetPerformUpdateWithCompletionHandler(completionHandler: ((NCUpdateResult) -> Void)) { let updated = refreshTheModel() if (updated) { view.setNeedsDisplay() } completionHandler(updated ? .NewData : .NoData) }

System opportunistically refreshes contentView controller conforms to NCWidgetProvidingImplements update delegate method

Page 202: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action
Page 203: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action
Page 204: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

NetworkingBackground sessions

Page 205: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

NetworkingNSURLSession

Background sessions

Page 206: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

NetworkingNSURLSession

Background sessionsTask performed by the system

Page 207: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

NetworkingNSURLSession

Background sessionsTask performed by the systemUpdates delivered to your extension as long as it stays alive

Page 208: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

NetworkingNSURLSession

Background sessionsTask performed by the systemUpdates delivered to your extension as long as it stays aliveError and event handled by the containing app

Page 209: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

NetworkingNSURLSession

Background sessionsTask performed by the systemUpdates delivered to your extension as long as it stays aliveError and event handled by the containing app

Page 210: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

NetworkingExtension API

let sc = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier( "com.example.my-download-session") sc.sharedContainerIdentifier = "group.com.example.my-app" let session = NSURLSession(configuration: sc, delegate: self, delegateQueue: NSOperationQueue.mainQueue()) let request = NSURLRequest(URL: NSURL(string: "https://www.apple.com/")!) let task = session.downloadTaskWithRequest(request) task?.resume()

Page 211: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

NetworkingExtension API

let sc = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier( "com.example.my-download-session") sc.sharedContainerIdentifier = "group.com.example.my-app" let session = NSURLSession(configuration: sc, delegate: self, delegateQueue: NSOperationQueue.mainQueue()) let request = NSURLRequest(URL: NSURL(string: "https://www.apple.com/")!) let task = session.downloadTaskWithRequest(request) task?.resume()

Page 212: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

NetworkingExtension API

let sc = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier( "com.example.my-download-session") sc.sharedContainerIdentifier = "group.com.example.my-app" let session = NSURLSession(configuration: sc, delegate: self, delegateQueue: NSOperationQueue.mainQueue()) let request = NSURLRequest(URL: NSURL(string: "https://www.apple.com/")!) let task = session.downloadTaskWithRequest(request) task?.resume()

Page 213: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

NetworkingExtension API

let sc = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier( "com.example.my-download-session") sc.sharedContainerIdentifier = "group.com.example.my-app" let session = NSURLSession(configuration: sc, delegate: self, delegateQueue: NSOperationQueue.mainQueue()) let request = NSURLRequest(URL: NSURL(string: “https://www.apple.com/")!) let task = session.downloadTaskWithRequest(request) task?.resume()

Page 214: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

NetworkingExtension API

let sc = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier( "com.example.my-download-session") sc.sharedContainerIdentifier = "group.com.example.my-app" let session = NSURLSession(configuration: sc, delegate: self, delegateQueue: NSOperationQueue.mainQueue()) let request = NSURLRequest(URL: NSURL(string: "https://www.apple.com/")!) let task = session.downloadTaskWithRequest(request) task?.resume()

Page 215: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

NetworkingExtension API

let sc = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier( "com.example.my-download-session") sc.sharedContainerIdentifier = "group.com.example.my-app" let session = NSURLSession(configuration: sc, delegate: self, delegateQueue: NSOperationQueue.mainQueue()) let request = NSURLRequest(URL: NSURL(string: "https://www.apple.com/")!) let task = session.downloadTaskWithRequest(request) task?.resume()

Page 216: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

NetworkingExtension API

let sc = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier( "com.example.my-download-session") sc.sharedContainerIdentifier = "group.com.example.my-app" let session = NSURLSession(configuration: sc, delegate: self, delegateQueue: NSOperationQueue.mainQueue()) let request = NSURLRequest(URL: NSURL(string: "https://www.apple.com/")!) let task = session.downloadTaskWithRequest(request) task?.resume()

Page 217: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

NetworkingContaining app API

func application(application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: () -> Void) { guard (identifier == "com.example.my-download-session") else { return } let sc = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier(identifier) sc.sharedContainerIdentifier = "group.com.example.my-app" self.session = NSURLSession(configuration: sc, delegate: self, delegateQueue: NSOperationQueue.mainQueue()) self.completionHandler = completionHandler }

Page 218: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

NetworkingContaining app API

func application(application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: () -> Void) { guard (identifier == "com.example.my-download-session") else { return } let sc = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier(identifier) sc.sharedContainerIdentifier = "group.com.example.my-app" self.session = NSURLSession(configuration: sc, delegate: self, delegateQueue: NSOperationQueue.mainQueue()) self.completionHandler = completionHandler }

Page 219: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

NetworkingContaining app API

func application(application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: () -> Void) { guard (identifier == "com.example.my-download-session") else { return } let sc = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier(identifier) sc.sharedContainerIdentifier = "group.com.example.my-app" self.session = NSURLSession(configuration: sc, delegate: self, delegateQueue: NSOperationQueue.mainQueue()) self.completionHandler = completionHandler }

Page 220: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

NetworkingContaining app API

func application(application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: () -> Void) { guard (identifier == "com.example.my-download-session") else { return } let sc = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier(identifier) sc.sharedContainerIdentifier = "group.com.example.my-app" self.session = NSURLSession(configuration: sc, delegate: self, delegateQueue: NSOperationQueue.mainQueue()) self.completionHandler = completionHandler }

Page 221: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

NetworkingContaining app API

func application(application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: () -> Void) { guard (identifier == "com.example.my-download-session") else { return } let sc = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier(identifier) sc.sharedContainerIdentifier = "group.com.example.my-app" self.session = NSURLSession(configuration: sc, delegate: self, delegateQueue: NSOperationQueue.mainQueue()) self.completionHandler = completionHandler }

Page 222: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

NetworkingContaining app API

func application(application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: () -> Void) { guard (identifier == "com.example.my-download-session") else { return } let sc = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier(identifier) sc.sharedContainerIdentifier = "group.com.example.my-app" self.session = NSURLSession(configuration: sc, delegate: self, delegateQueue: NSOperationQueue.mainQueue()) self.completionHandler = completionHandler }

Page 223: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

NetworkingContaining app API

func URLSessionDidFinishEventsForBackgroundURLSession(session: NSURLSession){ let sc = session.configuration guard (sc.identifier == "com.example.my-download-session") else { return } self.completionHandler!() self.session = nil }

Page 224: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

NetworkingContaining app API

func URLSessionDidFinishEventsForBackgroundURLSession(session: NSURLSession){ let sc = session.configuration guard (sc.identifier == "com.example.my-download-session") else { return } self.completionHandler!() self.session = nil }

Page 225: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

NetworkingContaining app API

func URLSessionDidFinishEventsForBackgroundURLSession(session: NSURLSession){ let sc = session.configuration guard (sc.identifier == "com.example.my-download-session") else { return } self.completionHandler!() self.session = nil }

Page 226: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

NetworkingContaining app API

func URLSessionDidFinishEventsForBackgroundURLSession(session: NSURLSession){ let sc = session.configuration guard (sc.identifier == "com.example.my-download-session") else { return } self.completionHandler!() self.session = nil }

Page 227: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

NetworkingContaining app API

func URLSessionDidFinishEventsForBackgroundURLSession(session: NSURLSession){ let sc = session.configuration guard (sc.identifier == "com.example.my-download-session") else { return } self.completionHandler!() self.session = nil }

Page 228: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

NetworkingwatchOS

Use background task assertions to protect small tasks

Page 229: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

NetworkingwatchOS

Use background task assertions to protect small tasks

WatchKit Tips and Tricks Presidio Friday 10:00AM

Page 230: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Sharing Secretskeychain-access-groups entitlement

Page 231: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Sharing SecretsAPI

// Add an item SecItemAdd({ kSecAttrAccessGroup: "com.example.your-app-group"}, result: NULL)

Page 232: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Sharing SecretsAPI

// Add an item SecItemAdd({ kSecAttrAccessGroup: "com.example.your-app-group"}, result: NULL)

Page 233: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Sharing SecretsAPI

// Add an item SecItemAdd({ kSecAttrAccessGroup: "com.example.your-app-group"}, result: NULL)

Page 234: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Sharing SecretsAPI

Automatic search behavior for query API

Security and Your Apps Mission Tuesday 4:30PM

Page 235: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Sharing SecretsAPI

Automatic search behavior for query API• SecItemUpdate

Security and Your Apps Mission Tuesday 4:30PM

Page 236: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Sharing SecretsAPI

Automatic search behavior for query API• SecItemUpdate• SecItemDelete

Security and Your Apps Mission Tuesday 4:30PM

Page 237: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Sharing SecretsAPI

Automatic search behavior for query API• SecItemUpdate• SecItemDelete• SecItemCopyMatching

Security and Your Apps Mission Tuesday 4:30PM

Page 238: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Sharing SecretsAPI

Automatic search behavior for query API• SecItemUpdate• SecItemDelete• SecItemCopyMatching

Security and Your Apps Mission Tuesday 4:30PM

Page 239: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Summary

Action and Share Extensions

Page 240: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Summary

Action and Share ExtensionsEnhanced Today widget

Page 241: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Summary

Action and Share ExtensionsEnhanced Today widgetGeneral best practices

Page 242: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

Related Sessions

WatchKit Tips and Tricks Presidio Friday 10:00AM

Security and Your Apps Mission Tuesday 4:30PM

Page 243: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action

More Information

DocumentationApp Extension Programming Guide

Sample CodeListerSample Photo Editing Extensionhttp://developer.apple.com/app-extensions

Technical SupportApple Developer ForumsDeveloper Technical Supporthttp://devforums.apple.com

General InquiriesCurt Rothert, App Frameworks [email protected]

Page 244: App Extension Best Practices - Apple Inc. · App Extension Best Practices Sophia Teutschler UIKit Engineer Ian Baird CoreOS Engineer App Frameworks Session 224. Agenda. Agenda Action