ios8勉強会@yahoo! japan "document provider"
DESCRIPTION
iOS8勉強会で話した「Document Provider」についての資料です。話せなかった部分は追加の資料で補っています。TRANSCRIPT
Document Providerヤフー株式会社
大西智也
2014/10/18
自己紹介
• 大西智也
• 新卒2年目
• iOS歴4年
• iOSアプリ中心に業務
アジェンダ
• 何ができるのか?
• Document Providerの構成
• 実装方法
• まとめ
何ができるのか?
DocumentProviderを実装すると
自分のアプリに対して他のアプリが ファイルの操作をすることができる
DocumentProviderを実装すると
自分のアプリに対して他のアプリが ファイルの操作をすることができる
Import MoveOpenExport
Document ProviderHostApp
Import
ドキュメントを渡す
Document ProviderHostApp
Export
ドキュメントをもらう
Document ProviderHostApp
• Open • ドキュメントを直接編集させる
• Move • ドキュメントを移動させる
4つの操作モード
• 最低1つ、最大4つサポートできる
• それぞれについてUIとロジックを実装しなければならない
Import MoveOpenExport
Document Providerの構成
Document Providerの構成
• DocumentPickerViewController Extension • UI • Import, Exportのサポート
• FileProvider Extension • Open, Moveのサポート
Document Providerの構成
• DocumentPickerViewController Extension • UI • Import, Exportのサポート
• FileProvider Extension • Open, Moveのサポート
別々のターゲットとして追加されるので注意
実装方法
Import MoveOpenExport
エクステンションを追加
エクステンションを追加
エクステンションを追加
Open, Moveをサポートするならチェックを入れる
Document Providerの構成
• DocumentPickerViewController Extension • UI • Import, Exportのサポート
• FileProvider Extension • Open, Moveのサポート
各種ファイルが追加される
• DocumentPickerViewController • MainInterface.storyboard • info.plist
info.plist <key>NSExtension</key> <dict> <key>NSExtensionAttributes</key> <dict> <key>UIDocumentPickerModes</key> <array> <string>UIDocumentPickerModeImport</string> <string>UIDocumentPickerModeExportToService</string> </array> <key>UIDocumentPickerSupportedFileTypes</key> <array> <string>public.content</string> </array> </dict> <key>NSExtensionMainStoryboard</key> <string>MainInterface</string> <key>NSExtensionPointIdentifier</key> <string>com.apple.fileprovider-ui</string> </dict>
サポートするモード
info.plist <key>NSExtension</key> <dict> <key>NSExtensionAttributes</key> <dict> <key>UIDocumentPickerModes</key> <array> <string>UIDocumentPickerModeImport</string> <string>UIDocumentPickerModeExportToService</string> </array> <key>UIDocumentPickerSupportedFileTypes</key> <array> <string>public.content</string> </array> </dict> <key>NSExtensionMainStoryboard</key> <string>MainInterface</string> <key>NSExtensionPointIdentifier</key> <string>com.apple.fileprovider-ui</string> </dict>
サポートするUTI
MainInterface.storyboard
UIの一部はシステムが 提供する
DocumentPickerViewController
• UIを管理する
• Import, Exportのロジックを実装する
• Document Pickerと略される
class DocumentPickerViewController: UIDocumentPickerExtensionViewController
Importで主に利用するメソッド
func prepareForPresentationInMode(mode: UIDocumentPickerMode)
• Document Providerが表示される直前に呼ばれる • 操作モードによってUIを変更する
Importで主に利用するメソッド
func dismissGrantingAccessToURL(url: NSURL!)
• ドキュメントのURLをHostAppに返す • UIを閉じる
class DocumentPickerViewController: UIDocumentPickerExtensionViewController { override func prepareForPresentationInMode(mode: UIDocumentPickerMode) { super.prepareForPresentationInMode(mode) switch mode { // Import, ExportのUIに変更
} } /** UIの処理など */ ! // ユーザがドキュメントを選んだとき、例えばCollectionViewのセルをタップした時 func didSelectDocument() { let URL = self.documentStorageURL.URLByAppendingPathComponent("hoge1.png") self.dismissGrantingAccessToURL(URL) } }
class DocumentPickerViewController: UIDocumentPickerExtensionViewController { override func prepareForPresentationInMode(mode: UIDocumentPickerMode) { super.prepareForPresentationInMode(mode) switch mode { // Import, ExportのUIに変更
} } /** UIの処理など */ ! // ユーザがドキュメントを選んだとき、例えばCollectionViewのセルをタップした時 func didSelectDocument() { let URL = self.documentStorageURL.URLByAppendingPathComponent("hoge1.png") self.dismissGrantingAccessToURL(URL) } }
class DocumentPickerViewController: UIDocumentPickerExtensionViewController { override func prepareForPresentationInMode(mode: UIDocumentPickerMode) { super.prepareForPresentationInMode(mode) switch mode { // Import, ExportのUIに変更
} } /** UIの処理など */ ! // ユーザがドキュメントを選んだとき、例えばCollectionViewのセルをタップした時 func didSelectDocument() { let URL = self.documentStorageURL.URLByAppendingPathComponent("hoge1.png") self.dismissGrantingAccessToURL(URL) } }
class DocumentPickerViewController: UIDocumentPickerExtensionViewController { override func prepareForPresentationInMode(mode: UIDocumentPickerMode) { super.prepareForPresentationInMode(mode) switch mode { // Import, ExportのUIに変更
} } /** UIの処理など */ ! // ユーザがドキュメントを選んだとき、例えばCollectionViewのセルをタップした時 func didSelectDocument() { let URL = self.documentStorageURL.URLByAppendingPathComponent("hoge1.png") self.dismissGrantingAccessToURL(URL) } }
class DocumentPickerViewController: UIDocumentPickerExtensionViewController { override func prepareForPresentationInMode(mode: UIDocumentPickerMode) { super.prepareForPresentationInMode(mode) switch mode { // Import, ExportのUIに変更
} } /** UIの処理など */ ! // ユーザがドキュメントを選んだとき、例えばCollectionViewのセルをタップした時 func didSelectDocument() { let URL = self.documentStorageURL.URLByAppendingPathComponent("hoge1.png") self.dismissGrantingAccessToURL(URL) } }
class DocumentPickerViewController: UIDocumentPickerExtensionViewController { override func prepareForPresentationInMode(mode: UIDocumentPickerMode) { super.prepareForPresentationInMode(mode) switch mode { // Import, ExportのUIに変更
} } /** UIの処理など */ ! // ユーザがドキュメントを選んだとき、例えばCollectionViewのセルをタップした時 func didSelectDocument() { let URL = self.documentStorageURL.URLByAppendingPathComponent("hoge1.png") self.dismissGrantingAccessToURL(URL) } }
class DocumentPickerViewController: UIDocumentPickerExtensionViewController { override func prepareForPresentationInMode(mode: UIDocumentPickerMode) { super.prepareForPresentationInMode(mode) switch mode { // Import, ExportのUIに変更
} } /** UIの処理など */ ! // ユーザがドキュメントを選んだとき、例えばCollectionViewのセルをタップした時 func didSelectDocument() { let URL = self.documentStorageURL.URLByAppendingPathComponent("hoge1.png") self.dismissGrantingAccessToURL(URL) } }
Export
• HostAppから渡されたドキュメントのURL
@NSCopying var originalURL: NSURL? { get }
FileProvider Extension
• Open, Moveをサポートする
• ファイルに対して直接アクセスされるので非常に複雑になる • コンフリクト • リモートファイル(ダウンロード、変更のアップロード、
通信状況の監視)
まとめ
• 他のアプリとのドキュメントのやりとりができるようになった
• Import, Exportは比較的簡単、Open, Moveは複雑
• ストレージ系、写真管理アプリはぜひ
参考資料
• 公式ドキュメント • https://developer.apple.com/library/ios/
documentation/General/Conceptual/ExtensibilityPG/FileProvider.html
• Dropbox • https://itunes.apple.com/jp/app/dropbox/
id327630330?mt=8
追加資料
Document Providerの表示方法
Document ProviderHostApp
表示
delegate
準備
• プロジェクトのiCloudのiCloud Documentsにチェックを入れる
iCloudのDocument Providerがデフォルトで表示されるため
UIDocumentMenuViewController
• DocumentPickerを呼び出すために使う
• 操作モードを指定して表示する
let menu = UIDocumentMenuViewController(documentTypes: self.UTIs, inMode: .Import) !menu.delegate = self self.showViewController(menu, sender: nil)
HostApp側に実装する
Document Providerの一覧が 表示される
// MARK: UIDocumentMenuDelegate func documentMenu(documentMenu: UIDocumentMenuViewController, didPickDocumentPicker documentPicker: UIDocumentPickerViewController) { ! documentPicker.delegate = self self.showViewController(documentPicker, sender: nil) ! }
ユーザが開きたいDocumentProviderを選んだ時
// MARK: UIDocumentMenuDelegate func documentMenu(documentMenu: UIDocumentMenuViewController, didPickDocumentPicker documentPicker: UIDocumentPickerViewController) { ! documentPicker.delegate = self self.showViewController(documentPicker, sender: nil) ! }
documentPickerはDocument ProviderのUI部分
DocumentPickerViewController
• UIを管理する
• Import, Exportのロジックを実装する
• Document Pickerと略される
class DocumentPickerViewController: UIDocumentPickerExtensionViewController
さきほどのスライド
// MARK: UIDocumentMenuDelegate func documentMenu(documentMenu: UIDocumentMenuViewController, didPickDocumentPicker documentPicker: UIDocumentPickerViewController) { ! documentPicker.delegate = self self.showViewController(documentPicker, sender: nil) ! }
documentPickerを表示する
// MARK: UIDocumentPickerDelegate func documentPicker(controller: UIDocumentPickerViewController, didPickDocumentAtURL url: NSURL) { ! println(url) ! }
デリゲートでドキュメントのURLが渡される
self.dismissGrantingAccessToURL(URL)
DocumentProvider側で以下のメソッドを呼ぶ