LoginSignup
11
12

More than 5 years have passed since last update.

Action Extensionメモ&サンプル

Posted at

Action Extensionはアプリから任意のデータを受け取り、処理を行い、結果を戻すことができる汎用的なエクステンションです。

action_extension.jpg

URLをWebViewで開き、全体のスクリーンショットをカメラロールに保存するサンプルを作成しました。
https://github.com/imk2o/Try-AppExtensions

処理の流れ

  • ビューコントローラがインスタンス化される
  • アプリより渡されたアイテムを取得し、任意の処理を行う
    • UIViewController#extensionContext
    • NSExtensionContext#inputItems
  • リクエストを完了する
    • NSExtensionContext#completeRequestReturningItems(_:completionHandler:)
    • NSExtensionContext#cancelRequestWithError(_:)

Info.plistの設定

Info.plistNSExtensionActivationRuleに、受入可能なデータタイプの設定を行います。

デフォルトでは全てを受け入れるTRUEPREDICATEが設定されているが、リジェクトされる可能性があるため適宜設定すること。

  • NSExtensionActivationSupportsAttachmentsWithMaxCount:
  • NSExtensionActivationSupportsAttachmentsWithMinCount
  • NSExtensionActivationSupportsFileWithMaxCount: 受入可能なファイル数
  • NSExtensionActivationSupportsImageWithMaxCount: 受入可能な画像数
  • NSExtensionActivationSupportsMovieWithMaxCount: 受入可能な動画数
  • NSExtensionActivationSupportsText: テキストは受入可能か?(Boolean)
  • NSExtensionActivationSupportsWebURLWithMaxCount: 受入可能なURL数
  • NSExtensionActivationSupportsWebPageWithMaxCount: 受入可能なWebページ数

アプリより渡されたアイテムの取得

アプリより渡されたアイテムはextensionContext.inputItemsに格納されています。受入可能な型として値を取り出します。

    override func viewDidLoad() {
        super.viewDidLoad()

        // 1つのアイテムを抽出(Info.plistの設定により制限されている)
        guard
            let item = self.extensionContext?.inputItems.first as? NSExtensionItem,
            let itemProvider = item.attachments?.first as? NSItemProvider
        else {
            return
        }

        // アイテムからURLを抽出
        if itemProvider.hasItemConformingToTypeIdentifier(kUTTypeURL as String) {
            itemProvider.loadItemForTypeIdentifier(kUTTypeURL as String, options: nil) { [weak self] (item, error) in
                if let error = error {
                    self?.extensionContext?.cancelRequestWithError(error)
                } else if let URL = item as? NSURL {
                    dispatch_async(dispatch_get_main_queue()) {
                        self?.loadURL(URL)
                    }
                }
            }
        }
    }

リクエストの完了

処理が成功した場合はNSExtensionContext#completeRequestReturningItems(_:completionHandler:)を呼び出します。このとき、アプリ側に処理したNSExtensionItemを返すこともできます。処理に失敗した場合はNSExtensionContext#cancelRequestWithError(_:)を呼び出します。

サンプルコードではWebページのキャプチャを行い、その画像の保存完了時に各ハンドラを呼び出しています。

    func image(image: UIImage, didFinishSavingWithError error: NSError?, contextInfo: UnsafeMutablePointer<Void>) {
        if let error = error {
            self.extensionContext?.cancelRequestWithError(error)
        } else {
            self.extensionContext?.completeRequestReturningItems(nil, completionHandler: nil)
        }
    }

参考

http://dev.classmethod.jp/references/ios-8-action-extension/
http://hack.sonix.asia/archives/936

11
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
12