web-dev-qa-db-fra.com

Partage de données entre une extension de partage iOS 8 et une application principale

Récemment, j'ai créé une simple extension de partage iOS 8 pour comprendre le fonctionnement du système. Comme Apple l’indique dans son App Extension Guide de programmation

Par défaut, votre application contenant et ses extensions n’ont pas d’accès direct aux conteneurs de l’autre.

Ce qui signifie que l'extension et l'application contenue ne partagent pas de données. Mais dans la même page, Apple apporte une solution:

Si vous souhaitez que votre application contenant et ses extensions puissent partager des données, utilisez Xcode ou le portail de développeur pour activer les groupes d'applications pour l'application et ses extensions. Ensuite, enregistrez le groupe d'applications sur le portail et spécifiez le groupe d'applications à utiliser dans l'application contenant.

Il devient alors possible d'utiliser NSUserDefaults pour partager des données entre l'application contenant et l'extension. C'est exactement ce que je voudrais faire. Mais pour une raison quelconque, cela ne fonctionne pas.

Dans la même page, Apple suggère les valeurs par défaut standard:

var defaults = NSUserDefaults.standardUserDefaults()

Dans une présentation WWDC (217), ils suggèrent un paquet commun:

var defaults = NSUserDefaults(suiteName: kDefaultsPackage)

De plus, j'ai activé les groupes d'application pour la cible d'application contenue et pour la cible d'extension, avec le même nom de groupe d'applications: XCode Target capabilities, App Groups

Mais toute cette configuration est pour rien. Je ne peux pas récupérer les données que j'ai stockées dans l'application contenante, à partir de l'extension. C'est comme si deux cibles utilisaient des stockages NSUserDefaults complètement différents.

Alors, 

  1. Existe-t-il une solution pour cette méthode?
  2. Comment partager des données simples entre l'application contenant et l'extension de partage? Les données ne sont que les informations d'identification de l'utilisateur pour une API.
58
Oguz Bilgener

Vous devez utiliser NSUserDefaults comme ceci:

Enregistrer des données:

objc

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

Rapide

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

Lire les données:

objc

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

Rapide

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

Cela fonctionnera bien!

41
foogry

Voici comment je l'ai fait:

  1. Ouvrez votre cible principale> Capacités> Groupes d’applications sur
  2. Ajoutez un nouveau groupe d'applications et assurez-vous qu'il est coché (par exemple, group.com.seligmanventures.LightAlarmFree)
  3. Ouvrez votre cible de surveillance (celle avec l'onglet Capacités)> Groupes d'applications configurés sur
  4. Ajoutez un nouveau groupe d'applications et assurez-vous qu'il est coché (par exemple, group.com.seligmanventures.LightAlarmFree - mais doit porter le même nom que le groupe ci-dessus).
  5. Enregistrez les données dans le groupe comme suit:

    var defaults = NSUserDefaults(suiteName: "group.com.seligmanventures.LightAlarmFree")
    defaults?.setObject("It worked!", forKey: "alarmTime")
    defaults?.synchronize()
    
  6. Récupérez les données du groupe comme suit:

    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
Charlie Seligman

Si tu as 

group.yourappgroup

utilisation 

var defaults = NSUserDefaults(suiteName: "yourappgroup")

Ça marche pour moi

5
Berni

Donc, apparemment, cela fonctionne, uniquement lorsque le nom du groupe est utilisé comme le nom de la suite pour NSUserDefaults.

La documentation indique que NSUserDefaults.standartUserDefaults () devrait également fonctionner, mais que cela ne fonctionne pas et qu'il s'agit probablement d'un bogue.

4
Oguz Bilgener

Dans mon scénario, je partage des données entre l'application iOS parent et WatchKit. J'utilise Xcode 6.3.1, iOS Deployment Target 8.3

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

Dans votre viewDidLoad, assurez-vous de synchroniser:

    override func viewDidLoad() {
    super.viewDidLoad()

    defaults?.synchronize()

}

Exemple de bouton d'envoi de texte mais vous pouvez bien sûr passer n'importe quoi:

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

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

}

Ensuite, de l'autre côté, assurez-vous que le groupe d'applications correspond:

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

Puis synchronize and cal: (Dans ce cas, "lblNumber" est une étiquette IBOutlet)

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

Ensuite, si vous souhaitez définir quelque chose de ce côté et le synchroniser à nouveau, il vous suffit de faire la même chose, de synchroniser et de vous assurer que le stringForKey que vous appelez de l'autre côté est le même:

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

J'espère que cela a du sens

3
Richmond

J'ai traduit dans la réponse de Swift Foogry et ça marche !!

Enregistrer des données:

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

Lire les données:

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

Vous devez utiliser NSUserDefaults comme suit et vous assurer que Vous avez activé le groupe d'applications dans votre profil provisoire et que le groupe d'applications doit être configuré en tant que symbole vert et qu'il doit être ajouté à votre profil provisoire et à votre identifiant 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

Vous pouvez partager des données en suivant les étapes ci-dessous:

  1. Sélectionnez votre projet -> Sélectionnez l'onglet Capacités -> Activer les groupes d'applications -> Cliquez sur '+' -> collez votre identifiant d'ensemble après le 'groupe .' Enable AppGroups in project capabilities tab
  2. Sélectionnez votre extension -> Sélectionnez l'onglet Capacités -> Activer les groupes d'applications -> Cliquez sur '+' -> collez votre identifiant d'ensemble après le 'groupe .' Enable AppGroups in Extension capabilities tab

    1. Placez le code ci-dessous dans votre application principale pour les données que vous souhaitez partager:

    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]; 

    1. Vous pouvez obtenir un objet en extension:

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

0
Anjali jariwala