これの Share 先に自分のアプリを表示させて、保存などの処理を行う。
やることは
- Target 追加
- App Groups の設定
- 証明書の修正
- Podfile 修正
- 新しいTargetの Info.plist 修正
- ShareViewController の実装
- データの保存先について
- Simulator で確認
です。
Target 追加
Xcode の File > New > Target から Share Extension を選択して作成。
こんな感じの物が出来上がる。
App Groups
次に、App Groups の設定をする。Target を超えてファイルを共有するのに必要。
先ほど作った Target > Signing & Capabilities > + Capability から AppGroups を選択。 group.com.hoge
を App Groups に追加する。メインの Target にも同様に group.com.hoge
を App Groups に追加する。
証明書の更新
証明書の設定が必要なので、 https://developer.apple.com/account/resources/identifiers/list から Capabilities の App Groups にチェックを入れ、 group.com.hoge
を登録する。
証明書の更新をしておく。
Podfile 修正
Share Extension でライブラリを使う必要があるなら Podfile も修正する。
例えば Realm を共有するなら以下のようにして pod update。
# Podfile target 'hoge' do use_frameworks! inhibit_all_warnings! pod 'RealmSwift' end target 'hogeShareExtension' do use_frameworks! inhibit_all_warnings! pod 'RealmSwift' end
Info.plist 修正
今回は画像を1枚だけ受ける設定にしたいので、Share Extension の Info.plist を以下のようにする。
NSExtensionAttributes を Dictionary に, NSExtensionActivationRule を Dictionary に, NSExtensionActivationSupportsImageWithMaxCount を 1 で設定する。
ShareViewController の実装
これまでの手順で、もう画像のシェア先に hoge アプリが出るはず。
画像を受け取った時の実装を書いていく。
import UIKit import Social import MobileCoreServices import RealmSwift class ShareViewController: SLComposeServiceViewController { override func isContentValid() -> Bool { // テキスト入力で Validation したい場合に設定する return true } // Post ボタンが押された // データの保存処理などここで行う override func didSelectPost() { let extensionItem = self.extensionContext?.inputItems.first as? NSExtensionItem let itemProvider = extensionItem?.attachments?.first let imageType = String(kUTTypeImage) // 渡されたデータが画像か確認 if itemProvider?.hasItemConformingToTypeIdentifier(imageType) == true { // データを読み込む itemProvider?.loadItem(forTypeIdentifier: imageType, options: nil) { item, error in // 画像の場合 URL が渡ってくる if let url = item as? URL { let image = UIImage(contentsOfFile: url.path) if let image = image { // 画像をローカルに保存やAPI実行するなどやりたいことをする // contentText から入力された文字が取得できる } } } } // 最後に実行する。データの保存処理などが非同期な場合は注意 self.extensionContext!.completeRequest(returningItems: [], completionHandler: nil) } override func configurationItems() -> [Any]! { // To add configuration options via table cells at the bottom of the sheet, return an array of SLComposeSheetConfigurationItem here. return [] } }
こんな感じで画像を受け取ることができる。
データの保存先について
これで共有ディレクトリを取得できます。
let url: URL? =FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.hoge")
メインのアプリとデータを共有するためには documentDirectory
などは使えません。
Realm でデータの共有をしたい場合などは以下のようにします。
var config = Realm.Configuration() config.fileURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.memoCamera")?.appendingPathComponent("default.realm") Realm.Configuration.defaultConfiguration = config
Simulator で確認
Scheme を変えてデバッグをします。Scheme を変えないと break point など使えません。
参考
以下の記事などが参考になります qiita.com