web-dev-qa-db-ja.com

アプリグループを使用したアプリ間でのデータの通信と永続化

iOS 8は昨日、App Groupsに関する新しいAPIを明らかにしました。以前はデータを共有してアプリ間で通信するのはちょっと面倒でしたが、App Groupsがそれを修正しようとしているのはまさにそれだと思います。

私のアプリでは、アプリグループを有効にして新しいグループを追加しましたが、使用方法に関するドキュメントが見つかりません。ドキュメントとAPIリファレンスには、グループの追加方法のみが記載されています。

それでは、App Groupsは実際に何をするつもりなのでしょうか?使用方法に関するドキュメントはどこかにありますか?

79
streem

アプリグループのもう1つの利点は、NSUserDefaultsデータベースを共有できることです。これは、App Extensions(通知センターウィジェット、カスタムキーボードなど)でも機能します。

アプリグループ内のすべてのアプリケーションでこのようにNSUserDefaultsオブジェクトを初期化すると、データベースを共有します。

Objective-C:

[[NSUserDefaults alloc] initWithSuiteName:@"<group identifier>"];

迅速:

NSUserDefaults(suiteName: "<group identifier>")

各アプリケーションの[NSUserDefaults standardUserDefaults]データベースのすべてがこのデータベースに引き継がれないことに注意してください。

documentation も正しい例を示しています(ベータ3以降)。

データベースを同期することを忘れないでください:

[yourDefaults synchronize];
79
Santa Claus

複数のアプリ間でNSUserDefaultsデータを共有する

アプリと拡張機能間、または2つのアプリ間でデフォルトを共有するには、次の手順を使用して設定にアプリグループを追加する必要があります。

  1. Project Navigatorで、*。xcodeprojファイルをクリックします(上部にあるはずです)。
  2. Project Navigatorの右側で、プロジェクトとターゲットを探します。ターゲットの下で、プライマリターゲットをクリックします([ターゲット]の下で最初にする必要があります)。
  3. 上部に向かって、[機能]タブをクリックします。
  4. [アプリグループ]セクションで、右側のスイッチをクリックして、アプリグループをオンにします。
  5. [+]ボタンをクリックして、group.com.company.myAppという名前のアプリグループを追加します。
  6. 他のアプリの同じ場所に移動すると、このグループを選択できるようになります。この共有データを使用するアプリごとにこのグループをオンにします。

注:Apple開発者ポータル(すべての証明書、識別子、デバイス、およびプロビジョニングプロファイルを表示するApple Webサイト)にアクセスすると、 [識別子]> [アプリグループ]に移動すると、この新しいアプリグループが表示されます。

データを保存するには:

var userDefaults = NSUserDefaults(suiteName: "group.com.company.myApp")!
userDefaults.setObject("user12345", forKey: "userId")
userDefaults.synchronize()

データを取得するには:

var userDefaults = NSUserDefaults(suiteName: "group.com.company.myApp")
if let testUserId = userDefaults?.objectForKey("userId") as? String {
  print("User Id: \(testUserId)")
}
69
TenaciousJay

既存のドキュメントの私の解釈によると、アプリケーショングループは主に拡張機能、より具体的にはウィジェットを対象としています。ウィジェットは、アプリと共存する独自のアプリケーションバンドルです。これらは個別のアプリケーションであり、独自のサンドボックスを持っているため、ファイルを共有するにはアプリグループを使用する必要があります。

ヘッダーをgrepしてから、必要なAPIが見つかったと思いますが、実際にはiOS 7の一部として組み込まれました。

NSFileManagerにはメソッドがありますcontainerURLForSecurityApplicationGroupIdentifier:アプリのアプリグループを有効にするときに作成した識別子を渡すことができます:

NSURL *containerURL = [[NSFileManager defaultManager] 
           containerURLForSecurityApplicationGroupIdentifier:@"group.com.company.app"];
36
Wayne Hartman

今日私がタップした重要なトラップの1つは次のとおりです。

多くのプロジェクトで、1つのアプリターゲットと、そのターゲットの構成ごとに異なるバンドル識別子が設定されているのを見ました。ここでは物事が面倒になります。開発者が意図したのは、デバッグ設定用のデバッグアプリとリリースターゲット用の本番アプリを作成することでした。

そのように設定すると、両方のアプリが同じように設定されたときに同じNSUserDefaultsを共有します

var userDefaults = NSUserDefaults(suiteName: "group.com.company.myApp")
userDefaults!.setObject("user12345", forKey: "userId")
userDefaults!.synchronize()

これは多くの場所で問題を引き起こします:

  1. ユーザーに特別なアプリ紹介画面が表示されたときに、キーにYESを設定したとします。もう一方のアプリもYESになり、イントロを表示しません。
  2. はい、一部のアプリはユーザーのデフォルトにoAuthトークンも保存します。とにかく...実装に応じて、アプリはトークンがあることを認識し、間違ったトークンを使用してデータの取得を開始します。これは奇妙なエラーで失敗する可能性が高いです。

この問題の一般的な解決策は、デフォルトのキーの前に構築された現在の構成を追加することです。構成に異なるバンドル識別子を設定することにより、実行時に構成を簡単に検出できます。次に、NSBundle.mainBundle()からバンドル識別子を読み取ります。同じバンドル識別子がある場合は、次のような異なるプリプロセッサマクロを設定する必要があります

#ifdef DEBUG
  NSString* configuration = @"debug";
#Elif RELEASE
  NSString* configuration = @"release";
#endif

Swiftでは、ほとんど同じように見えます。

#if DEBUG
  let configuration = "debug"
#elseif RELEASE
  let configuration = "release"
#endif
5
blackjacx

保存するために

let shared: NSUserDefaults = NSUserDefaults(suiteName: "group.abcapp")!
shared.setObject("abc.png", forKey: "favEmoji")
shared.synchronize()
2
Hardik Thakkar