前回はApp Groupの設定ができたところまででした。あとはUserDefaultで保存と読み出しを追加するだけです。
App Extension側でUserDefaultにコンテンツを保存します。
import UIKit
import Social
import MobileCoreServices
class ShareViewController: SLComposeServiceViewController {
//省略
override func didSelectPost() {
guard let inputItems = self.extensionContext?.inputItems as? [NSExtensionItem] else {
return
}
guard let providers = inputItems[0].attachments as? [NSItemProvider] else {
return
}
for provider in providers {
if provider.hasItemConformingToTypeIdentifier(kUTTypeText as String) {
provider.loadItem(forTypeIdentifier: kUTTypeText as String, options: nil, completionHandler: { (item, _) in
OperationQueue.main.addOperation {
if let textItem = item as? String {
print("??? AppExtension: textItem= \(textItem)") //printで出力
self.saveContent(content: textItem) //コンテンツをApp Groupのユーザーデフォルトに保存
}
}
})
break
}
}
self.extensionContext!.completeRequest(returningItems: [], completionHandler: nil)
}
//省略
/// コンテンツをApp Groupのユーザーデフォルトに保存
///
/// - Parameter content:
private func saveContent(content: String) {
guard let userDefaults = UserDefaults.init(suiteName: "group.jp.blowbend.ios.test.AwesomeApp") else {
print("userdefault: app group suite name is nil")
return
}
userDefaults.set(content, forKey: "user default key content")
userDefaults.synchronize()
}
}
AppGroupのUserDefaultといっても、UserDefault.init(suiteName:)でAppGroup IDを指定するだけで、ごくごく普通に使用できます。コンテンツを受け取る側の収容アプリケーションですが、AppDelegateで取得することにします。
もちろん、処理として必要な場所であればどこでもかまわないですが、didFinishLaunchingWithOptionsとapplicationWillEnterForegroundの2カ所で行っておけば、アプリを開いたタイミングで取得できると思います。ここで取得しておけば、アプリ内で自由に取り回しやすいのではないでしょうか。
import UIKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
getContentFromAppGroup() //App Groupのユーザーデフォルトからコンテンツを取得
return true
}
//省略
func applicationWillEnterForeground(_ application: UIApplication) {
getContentFromAppGroup() //App Groupのユーザーデフォルトからコンテンツを取得
}
//省略
// MARK: - METHODS FOR GET DATA FROM AppGroup
/// App Groupのユーザーデフォルトからコンテンツを取得
private func getContentFromAppGroup() {
guard let userDefaults = UserDefaults.init(suiteName: "group.jp.blowbend.ios.test.AwesomeApp") else {
print("userdefault: app group suite name is nil")
return
}
guard let content = userDefaults.object(forKey: "user default key content") ?? nil else {
print("userdefault: no content")
return
}
guard let textItem = content as? String else {
print("userdefault: no content")
return
}
userDefaults.removeObject(forKey: "user default key content") //無条件でデータの削除
print("??? Containing App: textItem= \(textItem)") //printで出力
}
}
コンテンツの2重取り込みを避けるために、取得できたか失敗したかに関わらず、無条件に削除しています。本来なら、取得したデータの内容をチェックしたりエラーハンドリングをきちんとしておくべきところですが、これはサンプルなので処理のシンプルさを優先して省略しました。
これを実行すると、データが受け渡されていることが確認できると思います。
今回はここまで。
「使ってみた(App Extension編) その5」に続きます。
♪♪♪
こちらもどうぞ。
使ってみた(App Extension編) その1
使ってみた(App Extension編) その2
使ってみた(App Extension編) その3
使ってみた(App Extension編) その5
使ってみた(App Extension編) おまけ