[Swift] iOS の共有メニューに追加できるアプリを作る(その 2:HostAppからデータを受け取るまで)
[Swift] iOS の共有メニューに追加できるアプリを作る(その1:共有メニューにアプリが表示されるまで)
Sponsor Link
例題の仕様
Host App から渡された画像ファイルを Containing App の背景に設定するようなアプリを作ってみます。
課題:Containing App と App Extension は、別アプリ
基本的に別アプリのような扱いとなります。(具体的には、別々の Sandbox が割り当てられるため、直接のやりとりができません)
何が問題かというと、App Extension が受け取ったデータをそのまま、Containing App に渡すことができないという点です。
例えば、UserDefaults にデータを保存しての受け渡しもできませんし、CoreDataを使ったやりとりも同様です。
解決法:App Groupを使う
App Group は、やりとりしたい Containing App と App Extension の両方で設定する必要があります。
Group 名は、”group”で始まる必要があり、通常は、Bundle Identifierと同様のcom.XXX.YYY.ZZZ のような名称を指定します。
App(Containing App)側の設定
App Extension 側の設定
App Group の共有リソースへのアクセス
UserDefaults を共有リソースとしたデータ共有
UserDefaults 経由で共有する時には、普段使っている UserDefaults.standard 経由のアクセスではなく、App Group名を使用したアクセスが必要となります。
App Group 名が、”group.com.smalldesksoftware.shareapp” とすると、以下のように、init(suiteName:)を使ってアクセスします。
let defaults = UserDefaults.init(suiteName: "group.com.smalldesksoftware.shareapp")
App Extension(データを渡す側)では、以下のようなコードでデータを保存します。
if let defaults = UserDefaults.init(suiteName: "group.com.smalldesksoftware.shareapp") {
defaults.set(true, forKey: "NeedToImportFromExtension")
}
Containing App(データを受け取る側)では、以下のようなコードでデータを受け取ることができます。
if defaults.bool(forKey: "NeedToImportFromExtension") {
print("need to import something from shared info")
defaults.set(false, forKey: "NeedToImportFromExtension")
}
UserDefaults では、大きなデータを保存することを推奨されていません。
ということで、UserDefaults 以外にも、App Group が設定されていることによりリソースを共有する方法があります。
FileSystem を使った共有リソースアクセス
containerURL(forSecurityApplicationGroupIdentifier:)を使って、アクセスします。
let shareURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.smalldesksoftware.shareapp")
あとは、適当なファイル名等を追加してアクセスします。
App Extension(データを渡す側)では、以下のようなコードでデータを保存します。
if let shareURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.smalldesksoftware.shareapp") {
let targetURL = shareURL.appendingPathComponent("image.jpg")
try? FileManager.default.copyItem(at: fileURL, to: targetURL)
}
Containing App(データを受け取る側)では、以下のようなコードでデータを受け取ることができます。
if let shareURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.com.smalldesksoftware.shareapp") {
imageURL = shareURL.appendingPathComponent("image.jpg")
// process imageURL
}
まとめ:Containing App と App Extension のデータ共有
共有には、UserDefautls と FileSystem を使えます。
FileSystem が使えるということは、CoreData 等も使えるということです。
ただし、Containing App と App Extension の競合は、自分で管理する必要があります。
説明は以上です。
Sponsor Link
[…] 続きの説明は、こちら。 […]