web-dev-qa-db-ja.com

iOS 8共有拡張機能とメインアプリ間でデータを共有する

最近、システムの仕組みを理解するために、簡単なiOS 8共有拡張機能を作成しています。 As Apple App Extension Programming Guide の状態

デフォルトでは、収容アプリとその拡張機能は互いのコンテナに直接アクセスできません。

つまり、拡張機能と含まれているアプリはデータを共有しません。しかし、同じページでAppleは解決策をもたらします:

含まれているアプリとその拡張機能でデータを共有できるようにする場合は、Xcodeまたは開発者ポータルを使用して、アプリとその拡張機能のアプリグループを有効にします。次に、ポータルにアプリグループを登録し、包含アプリで使用するアプリグループを指定します。

NSUserDefaultsを使用して、含まれているアプリと拡張機能の間でデータを共有することが可能になります。これはまさに私がやりたいことです。しかし、何らかの理由で機能しません。

同じページで、Appleは標準のデフォルトを提案します:

var defaults = NSUserDefaults.standardUserDefaults()

WWDCプレゼンテーション(217)で、彼らは一般的なパッケージを提案しています:

var defaults = NSUserDefaults(suiteName: kDefaultsPackage)

また、同じアプリグループ名で、含まれるアプリターゲットと拡張ターゲットの両方でアプリグループを有効にしました。 XCode Target capabilities, App Groups

しかし、このセットアップはすべて無料です。含まれているアプリに保存したデータを拡張機能から取得できません。 2つのターゲットがまったく異なるNSUserDefaultsストレージを使用しているようです。

そう、

  1. この方法の解決策はありますか?
  2. 含まれているアプリと共有拡張機能の間で簡単なデータを共有するにはどうすればよいですか?データは、APIのユーザー資格情報です。
61
Oguz Bilgener

NSUserDefaultsは次のように使用する必要があります。

データの保存:

objc

NSUserDefaults *shared = [[NSUserDefaults alloc] initWithSuiteName:@"group.yougroup"];
[shared setObject:object forKey:@"yourkey"];
[shared synchronize];

Swift

let defaults = UserDefaults(suiteName: "group.yourgroup")
defaults?.set(5.9, forKey: "yourKey")

データの読み取り:

objc

NSUserDefaults *shared = [[NSUserDefaults alloc] initWithSuiteName:@"group.yougroup"];
id value = [shared valueForKey:@"yourkey"];
NSLog(@"%@",value);

Swift

let defaults = UserDefaults(suiteName: "group.yourgroup")
let x = defaults?.double(forKey: "yourKey")
print(x)

これでうまくいきます!

46
foogry

ここに私がそれをした方法があります:

  1. メインアプリターゲットを開き、機能>オンに設定されたアプリグループを開きます
  2. 新しいアプリグループを追加し、チェックされていることを確認します(例:group.com.seligmanventures.LightAlarmFree)
  3. ウォッチターゲット([機能]タブがあるもの)を開き、[アプリグループ]をオンに設定します
  4. 新しいアプリグループを追加し、チェックされていることを確認します(例:group.com.seligmanventures.LightAlarmFree-ただし、上記のグループと同じ名前でなければなりません)
  5. 次のようにデータをグループに保存します。

    var defaults = NSUserDefaults(suiteName: "group.com.seligmanventures.LightAlarmFree")
    defaults?.setObject("It worked!", forKey: "alarmTime")
    defaults?.synchronize()
    
  6. 次のようにグループからデータを取得します。

    var defaults = NSUserDefaults(suiteName: "group.com.seligmanventures.LightAlarmFree") 
    defaults?.synchronize()
    
    // Check for null value before setting
    if let restoredValue = defaults!.stringForKey("alarmTime") {
        myLabel.setText(restoredValue)
    }
    else {
        myLabel.setText("Cannot find value")
    }
    
13

あなたが持っている場合

group.yourappgroup

つかいます

var defaults = NSUserDefaults(suiteName: "yourappgroup")

これは私のために働く

5
Berni

NSUserDefaultsのグループ名グループ名として使用されている場合にのみ動作するようです。

ドキュメントには、NSUserDefaults.standartUserDefaults()も機能するはずですが、機能しません。これはおそらくバグです。

5
Oguz Bilgener

私のシナリオでは、親iOSアプリとWatchKitの間でデータを共有しています。 Xcode 6.3.1、iOS Deployment Target 8.3を使用しています

var defaults = NSUserDefaults(suiteName: "group.yourappgroup.example")

ViewDidLoadで、同期を確認してください。

    override func viewDidLoad() {
    super.viewDidLoad()

    defaults?.synchronize()

}

テキストを送信するボタンの例ですが、もちろん何でも渡すことができます:

 @IBAction func btnSend(sender: UIButton) {
    var aNumber : Int = 0;
    aNumber = aNumber + 1

    //Pass anything with this line
    defaults?.setObject("\(aNumber)", forKey: "userKey")
    defaults?.synchronize()

}

次に、反対側でアプリグループが一致することを確認します。

 var defaults = NSUserDefaults(suiteName: "group.yourappgroup.example")

次に、同期とcal:(この場合、「lblNumber」はIBOutletラベルです)

defaults?.synchronize()
var tempVar = defaults!.stringForKey("userKey")!;
lblNumber.setText(tempVar);

次に、こちら側に何かを設定して同期したい場合は、同じことをして同期し、反対側で呼び出すstringForKeyが同じであることを確認します。

defaults?.setObject("sending sample text", forKey: "sampleKey")
defaults?.synchronize()

これが理にかなっていることを願って

3
Richmond

私はSwift foogry's answerで翻訳し、動作します!!

データを保存する:

let shared = NSUserDefaults(suiteName: "nameOfCreatedGroup")
shared("Saved String 1", forKey: "Key1")
shared("Saved String 2", forKey: "Key2")

データを読む:

let shared = NSUserDefaults(suiteName: "nameOfCreatedGroup")!
valueToRead1 = shared("Key1") as? String
valueToRead2 = shared("Key2") as? String
println(valueToRead1)   // Saved String 1
println(valueToRead2)   // Saved String 2
2
Matte.Car

以下の手順に従ってデータを共有できます。

1)プロジェクトを選択->機能を選択タブ->アプリグループを有効化->「+」をクリック->「グループ」の後にバンドルIDを貼り付け

Enable AppGroups in project capabilities tab

2)拡張機能を選択->機能を選択タブ->アプリグループを有効化->「+」をクリック->「グループ」の後にバンドルIDを貼り付け

Enable AppGroups in Extension capabilities tab

3)データを共有するメインアプリのコードの下に配置します。

NSUserDefaults * appGroupData = [[NSUserDefaults alloc]initWithSuiteName:@"group.com.appname"];
NSData * data = [NSKeyedArchiver archivedDataWithRootObject:[self allData]]; // Get my array which I need to share
[appGroupData setObject:data forKey:@"Data"];
[appGroupData synchronize];

4)拡張機能でオブジェクトを取得できます:

NSUserDefaults * appGroupData = [[NSUserDefaults alloc] initWithSuiteName:@"group.com.appname"];
NSData * data = [appGroupData dataForKey:@"Data"];
NSArray * arrReceivedData = [NSKeyedUnarchiver unarchiveObjectWithData:data];
1
Anjali jariwala

次のようにNSUserDefaultsを使用し、暫定プロファイルでアプリグループを有効にし、アプリグループを緑色のシンボルとして構成し、暫定プロファイルとBundleIDに追加する必要があります。

NSUserDefaults *sharedUserDefault = [[NSUserDefaults alloc] initWithSuiteName:@"group.yougroup"];
[sharedUserDefault setObject:object forKey:@"yourkey"];
[sharedUserDefault synchronize];

NSUserDefaults *sharedUserDefault = [[NSUserDefaults alloc] initWithSuiteName:@"group.yougroup"];
sharedUserDefault value = [sharedUserDefault valueForKey:@"yourkey"];
0
Hitesh Vaghela