iOS 8 a révélé une nouvelle API hier concernant les groupes d'applications. Avant, c'était un peu compliqué de partager des données et de communiquer entre des applications et je pense que c'est précisément ce que les groupes d'applications sont censés corriger.
Dans mon application, j'ai activé les groupes d'applications et ajouté un nouveau groupe, mais je ne trouve aucune documentation sur son utilisation. La documentation et les références d'API indiquent uniquement comment ajouter un groupe.
Alors, qu'est-ce que les groupes d'applications ont vraiment l'intention de faire? Existe-t-il une documentation quelque part sur son utilisation?
Un autre avantage de App Groups est la possibilité de partager une base de données NSUserDefaults
. Cela fonctionne également pour les extensions d'application (widgets du centre de notification, claviers personnalisés, etc.).
Initialisez votre objet NSUserDefaults
comme ceci dans toutes les applications du groupe d'applications et elles partageront la base de données:
Objectif c:
[[NSUserDefaults alloc] initWithSuiteName:@"<group identifier>"];
Rapide:
NSUserDefaults(suiteName: "<group identifier>")
Gardez à l'esprit tout de la [NSUserDefaults standardUserDefaults]
base de données pour chaque application ne sera pas transférée dans cette base de données.
Le documentation donne également un exemple correct (à partir de la version bêta 3).
Et n'oubliez pas de synchroniser la base de données:
[yourDefaults synchronize];
Partage des données NSUserDefaults entre plusieurs applications
Pour avoir les valeurs par défaut partagées entre une application et une extension ou entre 2 applications, vous devez ajouter un groupe d'applications dans vos paramètres en procédant comme suit:
Remarque: Si vous accédez au portail de développeur Apple (le site Web Apple qui affiche tous vos certificats, identifiants, Profils et profils de provisioning) et allez dans Identifiants> Groupes d’applications vous devriez voir ce nouveau groupe d’applications.
Pour stocker des données:
var userDefaults = NSUserDefaults(suiteName: "group.com.company.myApp")!
userDefaults.setObject("user12345", forKey: "userId")
userDefaults.synchronize()
pour récupérer des données:
var userDefaults = NSUserDefaults(suiteName: "group.com.company.myApp")
if let testUserId = userDefaults?.objectForKey("userId") as? String {
print("User Id: \(testUserId)")
}
Selon mon interprétation de la documentation existante, les groupes d’applications sont principalement destinés aux extensions, plus spécifiquement aux widgets. Les widgets sont leur propre ensemble d'applications qui coexistent avec votre application. Comme elles constituent une application distincte et ont donc leur propre sandbox, vous devrez utiliser des groupes d'applications pour partager des fichiers.
Après un peu d’en-tête, je pense avoir trouvé l’API nécessaire, mais elle a été intégrée à iOS 7.
NSFileManager
a une méthode dessus containerURLForSecurityApplicationGroupIdentifier:
où vous pouvez transmettre l'identifiant créé lors de l'activation des groupes d'applications pour vos applications:
NSURL *containerURL = [[NSFileManager defaultManager]
containerURLForSecurityApplicationGroupIdentifier:@"group.com.company.app"];
Un piège important que j'ai exploité aujourd'hui est le suivant:
Dans de nombreux projets, j'ai vu une cible d'application unique et avec différents identificateurs d'ensembles définis pour chaque configuration de cette cible. Ici, les choses se gâtent. Les développeurs souhaitaient créer une application de débogage pour la configuration de débogage et une application de production pour la cible de publication.
Si vous le faites, les deux applications partagent les mêmes NSUserDefaults lorsqu’elles sont configurées comme suit.
var userDefaults = NSUserDefaults(suiteName: "group.com.company.myApp")
userDefaults!.setObject("user12345", forKey: "userId")
userDefaults!.synchronize()
Cela pose des problèmes à plusieurs endroits:
La solution à ce problème en général consiste à préfixer les clés par défaut avec la configuration actuelle construite. Vous pouvez facilement détecter la configuration au moment de l'exécution en définissant différents identificateurs d'ensembles pour vos configurations. Ensuite, il suffit de lire l'identifiant de paquet dans NSBundle.mainBundle()
. Si vous avez les mêmes identifiants de lot, vous devez définir différentes macros de préprocesseur telles que
#ifdef DEBUG
NSString* configuration = @"debug";
#Elif RELEASE
NSString* configuration = @"release";
#endif
Dans Swift, il se ressemblera presque:
#if DEBUG
let configuration = "debug"
#elseif RELEASE
let configuration = "release"
#endif
à stocker
let shared: NSUserDefaults = NSUserDefaults(suiteName: "group.abcapp")!
shared.setObject("abc.png", forKey: "favEmoji")
shared.synchronize()