#WWDC18
Managing Documents In Your iOS Apps
•
Session 216
Brandon Tennant, Software Engineer
Thomas Deniau, Software Engineer
Rony Fadel, Software Engineer
© 2018 Apple Inc. All rights reserved. Redistribution or public display not permitted without written permission from Apple.
•
Document Management on iOS
•
What’s new?
•
Using the Document Management API
•
Raising the bar
•
Document Management on iOS
Document Management on iOS
What is it?
API for application developers
File provider API for cloud vendors
Files app
Document Management on iOS
Client API
Document Browser UIDocumentBrowserViewController
Document Picker UIDocumentPickerViewController
File Coordination NSFileCoordinator, UIDocument
File Operations NSFileManager
Building Great Document-based Apps in iOS 11 WWDC 2017
Document Management on iOS
File Provider API
File Provider Extension NSFileProviderExtension
File Provider Custom Actions FPUIActionExtensionViewController
File Provider Enhancements WWDC 2017
Document Management on iOS
File Provider UI
Sign in to your service using FPUIActionExtensionViewController
Your Drive Cancel
Sign In
Email or username
Password
Sign In
Your Drive Cancel
Your Drive Sign In Cancel
Sign In
Email or username
Password
Sign In
Cancel
Your Drive
Sign In
Document Management on iOS
File Provider adoption
Great adoption from cloud vendors and
application developers
Try adopting UIDocumentBrowserViewController
or creating a File Provider extension today!
•
What’s New?
Document Management on iOS NEW
File Provider–Validation tool
File Provider Validation tests your FileProvider
Extension and guides you to fix the issues
https://developer.apple.com/download/more/
Document Management on iOS NEW
File Provider–Validation tool
Download includes
• Source files to add to your project to enable testing
• An iOS app to run on your iPad
Modify your File Provider project
Install File Provider Validation on your device and
launch it
Your Drive
Your Drive
Your Drive
Document Management on iOS NEW
File Provider–Siri Shortcuts
Surfaces documents that were recently opened or created in Search and
the Lock Screen
You can also add a shortcut to Siri
Document Management on iOS
NEW
File Provider–Siri Shortcuts
Add NSFileProviderUsesUniqueItemIdentifiersAcrossDevices to your File Provider
Extension’s Info.plist
Introduction to Siri Shortcuts Hall 2 Tuesday 5:00PM
Document Management on iOS
NEW
File Provider–Siri Shortcuts
Add NSFileProviderUsesUniqueItemIdentifiersAcrossDevices to your File Provider
Extension’s Info.plist
Introduction to Siri Shortcuts Hall 2 Tuesday 5:00PM
Document Management on iOS NEW
Particles sample app
NEW
Document Management on iOS NEW
Particles sample app
Document Management on iOS NEW
Particles sample app
Main UI is a UIDocumentBrowserViewController
Document Management on iOS NEW
Particles sample app
Main UI is a UIDocumentBrowserViewController
Defines a file format
Document Management on iOS NEW
Particles sample app
Main UI is a UIDocumentBrowserViewController
Defines a file format
Implements state restoration
Document Management on iOS NEW
Particles sample app
Main UI is a UIDocumentBrowserViewController
Defines a file format
Implements state restoration
Import assets using UIDocumentPickerViewController
Document Management on iOS NEW
Particles sample app
Main UI is a UIDocumentBrowserViewController
Defines a file format
Implements state restoration
Import assets using UIDocumentPickerViewController
Available at https://developer.apple.com/download/more/
•
Interacting with Documents in Your App
Thomas Deniau, Software Engineer
•
Document picker and document browser
•
Document picker and document browser
•
Demo—add a document picker to an existing app
•
Document picker and document browser
•
Demo—add a document picker to an existing app
•
Document types
Interacting with Documents
What does it mean?
Interacting with Documents
What does it mean?
Providing UI to let your customers organize their documents
Your app
Interacting with Documents
What does it mean?
Providing UI to let your customers organize their documents
Accessing documents stored in the cloud Your app
Cloud services
Interacting with Documents
What does it mean?
Providing UI to let your customers organize their documents
Accessing documents stored in the cloud Your app
Accessing documents from another app
Other apps’ containers Cloud services
Document Picker vs Document Browser
Document Picker Document Browser
Document Picker vs Document Browser
Document Picker Document Browser
Browse local and cloud storage
✓ ✓
Document Picker vs Document Browser
Document Picker Document Browser
Browse local and cloud storage
✓ ✓
Access files from other apps
✓ ✓
Document Picker vs Document Browser
Document Picker Document Browser
Browse local and cloud storage
✓ ✓
Access files from other apps
✓ ✓
Use case Quick User Action Main document browsing UI of your app
Document Browser
Main document browsing UI
of a document-based application
UIDocumentBrowserViewController
Starting point of your app
UIDocumentBrowserViewController
Starting point of your app
Full screen
UIDocumentBrowserViewController
Starting point of your app
Full screen
Open and organize your documents
UIDocumentBrowserViewController
Starting point of your app
Full screen
Open and organize your documents
All the features of the Files App
UIDocumentBrowserViewController
Starting point of your app
Full screen
Open and organize your documents
All the features of the Files App
Can be customized
UIDocumentBrowserViewController
Starting point of your app
Full screen
Open and organize your documents
All the features of the Files App
Can be customized
• With your own buttons
UIDocumentBrowserViewController
Starting point of your app
Full screen
Open and organize your documents
All the features of the Files App
Can be customized
• With your own buttons
• To match your app’s look
UIDocumentBrowserViewController
Starting point of your app
Full screen
Open and organize your documents
All the features of the Files App
Can be customized
• With your own buttons
• To match your app’s look
Present your own UI on top
UIDocumentBrowserViewController
The Document Browser is the entry point of your app
Best practice is to make it the root view controller
UIDocumentBrowserViewController
The Document Browser is the entry point of your app
Best practice is to make it the root view controller
Can also be presented full screen
UIDocumentBrowserViewController
Getting started
UIDocumentBrowserViewController
Getting started
UIDocumentBrowserViewController
Getting started
UIDocumentBrowserViewController
Customization
UIDocumentBrowserViewController
Customization
Add your own buttons
UIDocumentBrowserViewController
Customization
Add your own buttons
Set colors and themes
UIDocumentBrowserViewController
Customization
Add your own buttons
Set colors and themes
Customize the open/close document animations
UIDocumentBrowserViewController
Customization
Add your own buttons
Set colors and themes
Customize the open/close document animations
Building Great Document-based Apps in iOS 11 WWDC 2017
UIDocumentBrowserViewController
Customization
Add your own buttons
Set colors and themes
Customize the open/close document animations
Sample code available
Building Great Document-based Apps in iOS 11 WWDC 2017
Document Picker
Open an asset stored in the cloud
or in another app
UIDocumentPickerViewController
Documents might be in multiple locations
Your container
UIDocumentPickerViewController
Documents might be in multiple locations
Your container
Other apps’ containers Cloud services
UIDocumentPickerViewController
Documents might be in multiple locations
Your container
Other apps’ containers Cloud services
UIDocumentPickerViewController
Documents might be in multiple locations
Access / copy / move documents
Your container
Other apps’ containers Cloud services
UIDocumentPickerViewController
Documents might be in multiple locations
Access / copy / move documents
Your container
Other apps’ containers Cloud services
UIDocumentPickerViewController
Documents might be in multiple locations
Access / copy / move documents
Quick user action Your container
Other apps’ containers Cloud services
UIDocumentPickerViewController
Your container
Use a document picker to
Other apps’ containers Cloud services
UIDocumentPickerViewController
Your container
Use a document picker to
Access files in the cloud
(.open)
Other apps’ containers Cloud services
UIDocumentPickerViewController
Your container
Use a document picker to
Access files in the cloud
(.open)
Move files to the cloud
(.moveToService)
Other apps’ containers Cloud services
UIDocumentPickerViewController
Your container
Use a document picker to
Access files in the cloud
(.open)
Move files to the cloud
(.moveToService)
Copy from/to the cloud
(.import,
.exportToService)
Other apps’ containers Cloud services
Example—Access a Video from the Cloud
Create a UIDocumentPickerViewController and present it
let picker = UIDocumentPickerViewController(documentTypes: [kUTTypeVideo as String],
in: .open)
picker.delegate = self
self.present(picker, animated: true)
Get the selected file URL
override func documentPicker(_ controller: UIDocumentPickerViewController,
didPickDocumentsAt urls: [URL]) {
// use the retrieved URLs
}
Example—Access a Video from the Cloud
Create a UIDocumentPickerViewController and present it
let picker = UIDocumentPickerViewController(documentTypes: [kUTTypeVideo as String],
in: .open)
picker.delegate = self
self.present(picker, animated: true)
Get the selected file URL
override func documentPicker(_ controller: UIDocumentPickerViewController,
didPickDocumentsAt urls: [URL]) {
// use the retrieved URLs
}
Example—Access a Video from the Cloud
Create a UIDocumentPickerViewController and present it
let picker = UIDocumentPickerViewController(documentTypes: [kUTTypeVideo as String],
in: .open)
picker.delegate = self
self.present(picker, animated: true)
Get the selected file URL
override func documentPicker(_ controller: UIDocumentPickerViewController,
didPickDocumentsAt urls: [URL]) {
// use the retrieved URLs
}
Example—Access a Video from the Cloud
Create a UIDocumentPickerViewController and present it
let picker = UIDocumentPickerViewController(documentTypes: [kUTTypeVideo as String],
in: .open)
picker.delegate = self
self.present(picker, animated: true)
Get the selected file URL
override func documentPicker(_ controller: UIDocumentPickerViewController,
didPickDocumentsAt urls: [URL]) {
// use the retrieved URLs
}
Example—Access a Video from the Cloud
Create a UIDocumentPickerViewController and present it
let picker = UIDocumentPickerViewController(documentTypes: [kUTTypeVideo as String],
in: .open)
picker.delegate = self
self.present(picker, animated: true)
Get the selected file URL
override func documentPicker(_ controller: UIDocumentPickerViewController,
didPickDocumentsAt urls: [URL]) {
// use the retrieved URLs
}
•
Demo
Document Types
Document Types let the system know which files your application handles
Document Types
Document Types
Important! They let iOS—
Document Types
Important! They let iOS—
• open your app when a file is tapped in the Files app
Document Types
Important! They let iOS—
• open your app when a file is tapped in the Files app
• show your app in the Share Sheet
Document Types
Important! They let iOS—
• open your app when a file is tapped in the Files app
• show your app in the Share Sheet
• use the proper icon for your documents
Document Types
Two steps—
• Declaring the type if it is not already declared by iOS
• Claiming that you can view or edit files of this type
Declaring a Type
Do you need to declare it?
Declaring a Type
Do you need to declare it?
Standard
file type
Declaring a Type
Do you need to declare it?
Standard
file type
Already declared
by iOS?
Declaring a Type
Do you need to declare it?
Standard
file type
Already declared
by iOS?
https://developer.apple.com/library/content/documentation/Miscellaneous/Reference/UTIRef/Articles/System-
DeclaredUniformTypeIdentifiers.html
Declaring a Type
Do you need to declare it?
Standard
file type
Already declared
by iOS?
Yes
Nothing to do
https://developer.apple.com/library/content/documentation/Miscellaneous/Reference/UTIRef/Articles/System-
DeclaredUniformTypeIdentifiers.html
Declaring a Type
Do you need to declare it?
Standard
file type
Your own file type
Already declared
by iOS?
Yes
Nothing to do Declare as exported
https://developer.apple.com/library/content/documentation/Miscellaneous/Reference/UTIRef/Articles/System-
DeclaredUniformTypeIdentifiers.html
Declaring a New File Type
Info.plist
Use the Xcode UI
Declaring a New File Type
A type definition is—
An identifier
(UTTypeIdentifier)
Declaring a New File Type
A type definition is—
An identifier
(UTTypeIdentifier)
Declaring a New File Type
A type definition is—
Parent types (the type “conforms to” them) (UTTypeConformsTo)
Declaring a New File Type
A type definition is—
Parent types (the type “conforms to” them) (UTTypeConformsTo)
Type Conformance
Types form a tree
Type Conformance
Types form a tree
public.jpeg
Type Conformance
Types form a tree
public.jpeg public.heif-standard
Type Conformance
Types form a tree
public.image
public.jpeg public.heif-standard
Type Conformance
Types form a tree
public.content
public.image
public.jpeg public.heif-standard
Type Conformance
Types form a tree
public.content
public.spreadsheet public.image
public.jpeg public.heif-standard
Type Conformance
Types form a tree
public.content
public.spreadsheet public.image com.example….Particles
public.jpeg public.heif-standard
Type Conformance
Types form a tree
public.content
public.spreadsheet public.image com.example….Particles
public.jpeg public.heif-standard
Type Conformance
Second tree to describe the on-disk format
public.content
…particles
Type Conformance
Second tree to describe the on-disk format
public.data
public.content
Single file on disk
…particles
Type Conformance
Second tree to describe the on-disk format
public.data com.apple.package
public.content
Single file on disk File package
…particles
Type Conformance
Second tree to describe the on-disk format
public.data com.apple.package
public.content
Single file on disk File package
…particles
Type Conformance
public.item
Root type
Second tree to describe the on-disk format
public.data com.apple.package
public.content
Single file on disk File package
…particles
Declaring a New File Type
My type conforms to “public.data, public.content”
Declaring a New File Type
My type conforms to “public.data, public.content”
Declaring a New File Type
Declaring a file extension—(UTTypeTagSpecification)
“Files with the .particles extension are of this type”
Declaring a New File Type
Declaring a file extension—(UTTypeTagSpecification)
“Files with the .particles extension are of this type”
Declaration—done!
Declaring a Type
Do you need to declare it?
Standard
file type
Your own file type
Already declared
by iOS?
Yes
Nothing to do Declare as exported
Declaring a Type
Do you need to declare it?
Standard
file type
Your own file type
Already declared
by iOS?
Yes
Nothing to do Declare as exported
Declaring a Type
Do you need to declare it?
Standard
file type
Owned by Your own file type
Already declared
by iOS? another app
Yes
Nothing to do Declare as exported
Declaring a Type
Do you need to declare it?
Standard
file type
Owned by Your own file type
Already declared
by iOS? another app
Yes
Nothing to do Declare as imported Declare as exported
Declaring a Type
Do you need to declare it?
Standard
file type
Owned by Your own file type
Already declared
by iOS? another app
Yes No
Nothing to do Declare as imported Declare as exported
Claiming Support for a Type
Once the type is defined, you need to claim support for it in Info.plist
Claiming Support for a Type
Type identifier defined previously
Claiming Support for a Type
Type identifier defined previously
Claiming Support for a Type—Handler Rank
Claiming Support for a Type—Handler Rank
Claiming Support for a Type—Handler Rank
Three choices
Claiming Support for a Type—Handler Rank
Three choices
Owner if you own this type
Claiming Support for a Type—Handler Rank
Three choices
Owner if you own this type
Default if you can edit this type
Claiming Support for a Type—Handler Rank
Three choices
Owner if you own this type
Default if you can edit this type
Alternate if you can read it
Claiming Support for a Type—Handler Rank
Three choices
Owner if you own this type
Default if you can edit this type
Alternate if you can read it
⚠ Rules are different on macOS
https://developer.apple.com/library/content/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/plist/info/CFBundleDocumentTypes
Claiming Support for a Type
Be as specific as possible
Don't claim support for catch-alls like public.data or public.content
What Can You Do?
What Can You Do?
Use a Document Browser or Document Picker to access documents
What Can You Do?
Use a Document Browser or Document Picker to access documents
Your customers can access their favorite cloud vendor
What Can You Do?
Use a Document Browser or Document Picker to access documents
Your customers can access their favorite cloud vendor
Consider using UIDocumentBrowserViewController instead of your
custom browser
What Can You Do?
Use a Document Browser or Document Picker to access documents
Your customers can access their favorite cloud vendor
Consider using UIDocumentBrowserViewController instead of your
custom browser
Configure the Document Types supported by your app in Xcode
•
Raising the Bar
Rony Fadel, Software Engineer
Your App and the Sandbox
// MARK: UIDocumentBrowserViewControllerDelegate
func documentBrowser(_ controller: UIDocumentBrowserViewController,
didPickDocumentURLs documentURLs: [URL])
// MARK: UIDocumentPickerDelegate
func documentPicker(_ controller: UIDocumentPickerViewController,
didPickDocumentsAt urls: [URL])
Your App and the Sandbox
// MARK: UIDocumentBrowserViewControllerDelegate
func documentBrowser(_ controller: UIDocumentBrowserViewController,
didPickDocumentURLs documentURLs: [URL])
// MARK: UIDocumentPickerDelegate
func documentPicker(_ controller: UIDocumentPickerViewController,
didPickDocumentsAt urls: [URL])
Your App and the Sandbox
// MARK: UIDocumentBrowserViewControllerDelegate
func documentBrowser(_ controller: UIDocumentBrowserViewController,
didPickDocumentURLs documentURLs: [URL])
// MARK: UIDocumentPickerDelegate
func documentPicker(_ controller: UIDocumentPickerViewController,
didPickDocumentsAt urls: [URL])
Your App and the Sandbox
Document Picker
URL
Your App
Your App and the Sandbox
URL
Your App
Your App and the Sandbox
URL
Your App
Error Domain=NSCocoaErrorDomain Code=257 "The file “<filename>” couldn’t be opened
because you don’t have permission to view it." UserInfo={NSFilePath=<path-to-
document>, NSUnderlyingError=0xFFFFFFFFF {Error Domain=NSPOSIXErrorDomain Code=1
"Operation not permitted"}}
Your App and the Sandbox
App Container
Your App
Other App
Cloud Service Container
App
Container
Cloud Service
Your App and the Sandbox
App Container
Your App
Other App
Unrestricted
Cloud Service Container
access
App
Container
Cloud Service
Your App and the Sandbox
App Container
Your App
Restricted
access
Other App
Unrestricted
Cloud Service Container
access
App
Container
Cloud Service
Your App and the Sandbox
Your App
App Container
Restricted
Unrestricted access
access
App
Container Other App
Your App and the Sandbox
URL
Your App
App Container
Restricted
Unrestricted access
access
App
Container Other App
Your App and the Sandbox
Security
URL URLscoped
Your App resource
App Container
Restricted
Unrestricted access
access
App
Container Other App
Your App and the Sandbox
Security
URL URLscoped
Your App resource
App Container
Restricted
Unrestricted access
access
App
Container Other App
func startAccessingSecurityScopedResource() -> Bool
func stopAccessingSecurityScopedResource()
Your App and the Sandbox
Security
URL URLscoped
Your App resource
App Container
Access
Unrestricted granted
access
App
Container Other App
func startAccessingSecurityScopedResource() -> Bool
func stopAccessingSecurityScopedResource()
Your App and the Sandbox
Security
URL URLscoped
Your App resource
App Container
Restricted
Unrestricted access
access
App
Container Other App
func startAccessingSecurityScopedResource() -> Bool
func stopAccessingSecurityScopedResource()
Your App and the Sandbox
Your App and the Sandbox
let didStartAccessing = url.startAccessingSecurityScopedResource()
defer {
if didStartAccessing {
url.stopAccessingSecurityScopedResource()
}
}
// do something with URL
Your App and the Sandbox
let didStartAccessing = url.startAccessingSecurityScopedResource()
defer {
if didStartAccessing {
url.stopAccessingSecurityScopedResource()
}
}
// do something with URL
Your App and the Sandbox
let didStartAccessing = url.startAccessingSecurityScopedResource()
defer {
if didStartAccessing {
url.stopAccessingSecurityScopedResource()
}
}
// do something with URL
Your App and the Sandbox
let didStartAccessing = url.startAccessingSecurityScopedResource()
defer {
if didStartAccessing {
url.stopAccessingSecurityScopedResource()
}
}
// do something with URL
Balance start/stopAccessing calls
Your App and the Sandbox
let didStartAccessing = url.startAccessingSecurityScopedResource()
defer {
if didStartAccessing {
url.stopAccessingSecurityScopedResource()
}
}
// do something with URL
Balance start/stopAccessing calls
Only call stopAccessing if startAccessing returns true
Your App and the Sandbox
let didStartAccessing = url.startAccessingSecurityScopedResource()
defer {
if didStartAccessing {
url.stopAccessingSecurityScopedResource()
}
}
// do something with URL
Balance start/stopAccessing calls
Only call stopAccessing if startAccessing returns true
Keep resource access time as small as possible
Your App and the Sandbox
let didStartAccessing = url.startAccessingSecurityScopedResource()
defer {
if didStartAccessing {
url.stopAccessingSecurityScopedResource()
}
}
// do something with URL
Balance start/stopAccessing calls
Only call stopAccessing if startAccessing returns true
Keep resource access time as small as possible
When in doubt, call these APIs
Coordinating File Access
Your App Other App
Cloud Service Container
Cloud Service
Coordinating File Access
Your App Other App
Cloud Service Container
Cloud Service
Coordinating File Access
Your App Other App
Cloud Service Container
Cloud Service
Coordinating File Access
Coordinating File Access
File Coordination—NSFileCoordinator and NSFilePresenter
Coordinating File Access
File Coordination—NSFileCoordinator and NSFilePresenter
System-wide multiple reader/single writer lock
Coordinating File Access
File Coordination—NSFileCoordinator and NSFilePresenter
System-wide multiple reader/single writer lock
Instructs the system to download the document
Make My Life Simpler!
UIDocument
Make My Life Simpler!
UIDocument
Available since iOS 5
Make My Life Simpler!
UIDocument
Available since iOS 5
Recommended way for displaying and editing your documents
Make My Life Simpler!
UIDocument
Available since iOS 5
Recommended way for displaying and editing your documents
No need to call start/stopAccessingSecurityScopedResource
Make My Life Simpler!
UIDocument
Available since iOS 5
Recommended way for displaying and editing your documents
No need to call start/stopAccessingSecurityScopedResource
Handles file coordination for you
Make My Life Simpler!
UIDocument
Available since iOS 5
Recommended way for displaying and editing your documents
No need to call start/stopAccessingSecurityScopedResource
Handles file coordination for you
Building Document Based Apps WWDC 2015
Your App
Foreground
Your App
Foreground Background
Your App
Foreground Background Suspended
Your App
Memory Pressure
Foreground Background Suspended Terminated
Your App
Memory Pressure
Foreground Background Suspended Terminated
Relaunched
Your App
Memory Pressure
Foreground Background Suspended Terminated
Relaunched
Restore the UI State
State Restoration
How do we implement it?
URL Cloud Service Container
Cloud Service
State Restoration
How do we implement it?
URL Cloud Service Container
Cloud Service
State Restoration
How do we implement it?
URL Cloud Service Container
Cloud Service
State Restoration
How do we implement it?
URL Cloud Service Container
Cloud Service
Document could have been moved or renamed
State Restoration
How do we implement it?
URL Cloud Service Container
Cloud Service
Document could have been moved or renamed
URL loses security scope when encoded
State Restoration
How do we implement it?
Bookmark Cloud Service Container
Cloud Service
State Restoration
How do we implement it?
Bookmark Cloud Service Container
Cloud Service
State Restoration
How do we implement it?
// Save security scoped bookmark
let bookmarkData = try? url.bookmarkData()
// Restore security scoped bookmark
var bookmarkDataIsStale = false
let documentURL = try? URL(resolvingBookmarkData: bookmarkData,
bookmarkDataIsStale: &bookmarkDataIsStale)
State Restoration
How do we implement it?
// Save security scoped bookmark
let bookmarkData = try? url.bookmarkData()
// Restore security scoped bookmark
var bookmarkDataIsStale = false
let documentURL = try? URL(resolvingBookmarkData: bookmarkData,
bookmarkDataIsStale: &bookmarkDataIsStale)
State Restoration
How do we implement it?
// Save security scoped bookmark
let bookmarkData = try? url.bookmarkData()
// Restore security scoped bookmark
var bookmarkDataIsStale = false
let documentURL = try? URL(resolvingBookmarkData: bookmarkData,
bookmarkDataIsStale: &bookmarkDataIsStale)
•
Demo
Copy to
Copy to
Open in place
Open in place
Open In Place
Adoption
Open In Place
Adoption
Already enabled in "Document Based App" template
Open In Place
Adoption
Already enabled in "Document Based App" template
Add LSSupportsOpeningDocumentsInPlace key to Info.plist
Open In Place
Adoption
Open In Place
Adoption
func application(_ app: UIApplication, open inputURL: URL,
options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool
Open In Place
Adoption
func application(_ app: UIApplication, open inputURL: URL,
options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool
Document Browser based apps
func revealDocument(at url: URL, importIfNeeded: Bool,
completion: ((URL?, Error?) -> Void)? = nil)
// Present the document in the completion handler
Progress reporting
Progress reporting
Support cancellation
Open In Place
Progress reporting
Open In Place
Progress reporting
Free when you call revealDocument on UIDocumentBrowserViewController
Open In Place
Progress reporting
Free when you call revealDocument on UIDocumentBrowserViewController
UIDocument conforms to ProgressReporting
extension UIDocument: ProgressReporting {
var progress: Progress? { get }
}
Open In Place
Progress reporting
Free when you call revealDocument on UIDocumentBrowserViewController
UIDocument conforms to ProgressReporting
extension UIDocument: ProgressReporting {
var progress: Progress? { get }
}
Ship it!
Raising the Bar
Raising the Bar
Adopt UIDocument
Raising the Bar
Adopt UIDocument
Adopt start/stopAccessing best practices
Raising the Bar
Adopt UIDocument
Adopt start/stopAccessing best practices
Coordinate file access
Raising the Bar
Adopt UIDocument
Adopt start/stopAccessing best practices
Coordinate file access
Implement state restoration
Raising the Bar
Adopt UIDocument
Adopt start/stopAccessing best practices
Coordinate file access
Implement state restoration
Implement Open In Place and report progress
Summary
Summary
What did we see today?
Summary
What did we see today?
• Document browser and document picker
Summary
What did we see today?
• Document browser and document picker
• Raising the bar
Summary
What did we see today?
• Document browser and document picker
• Raising the bar
• Siri Shortcuts
Summary
What did we see today?
• Document browser and document picker
• Raising the bar
• Siri Shortcuts
• FileProvider and FileProviderUI
More Information
https://developer.apple.com/wwdc18/216
Introduction to Siri Shortcuts WWDC 2018