Kommunikation und Speicherung von Daten zwischen Apps mit App-Gruppen

85

iOS 8 hat gestern eine neue API für App-Gruppen veröffentlicht. Früher war es ziemlich chaotisch, Daten auszutauschen und zwischen Apps zu kommunizieren, und ich glaube, genau das soll App Groups korrigieren.

In meiner App habe ich App-Gruppen aktiviert und eine neue Gruppe hinzugefügt, aber ich kann keine Dokumentation zur Verwendung finden. Dokumentations- und API-Referenzen geben nur an, wie eine Gruppe hinzugefügt wird.

Was sollen App-Gruppen wirklich tun? Gibt es irgendwo eine Dokumentation zur Verwendung?

Streem
quelle

Antworten:

81

Ein weiterer Vorteil für App-Gruppen ist die Möglichkeit, eine NSUserDefaultsDatenbank gemeinsam zu nutzen. Dies funktioniert auch für App-Erweiterungen (Benachrichtigungscenter-Widgets, benutzerdefinierte Tastaturen usw.).

Initialisieren Sie Ihr NSUserDefaultsObjekt wie folgt in allen Anwendungen in der App-Gruppe und sie teilen die Datenbank:

Ziel c:

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

Schnell:

NSUserDefaults(suiteName: "<group identifier>")

Beachten Sie, dass nicht alles aus der [NSUserDefaults standardUserDefaults]Datenbank für jede Anwendung in diese Datenbank übertragen wird.

Die Dokumentation enthält ebenfalls ein korrektes Beispiel (ab Beta 3).

Und vergessen Sie nicht, die Datenbank zu synchronisieren:

[yourDefaults synchronize];
Weihnachtsmann
quelle
2
Funktioniert nur mit Simulator (XCode 6 Beta 5, iOS 8 Beta 5)
iOS Dev
8
HINWEIS: Wenn Sie dies mit einer iOS 8-Erweiterung (z. B. Tastatur) verwenden, müssen Sie sicherstellen, dass Ihre Erweiterung in der Datei Info.plist RequestsOpenAccess = YES enthält.
Kiran Panesar
1
Ich habe RequestsOpenAccess = YES ausgeführt und folge den Anweisungen, aber es funktioniert nicht für mich auf dem Gerät und funktioniert einwandfrei auf dem Emulator, etwas spezielles für das Gerät?
MAC
Das gleiche Problem mit mir, ich habe die Freigabeerweiterung in meine App integriert, sie funktioniert auf dem Simulator, aber nicht auf dem realen Gerät. Ich habe RequestOpenAccess = YES hinzugefügt, aber es funktioniert nicht. Meine Frage lautet stackoverflow.com/questions/30489894/ …
Ravi Ojha
3
@ MikeRichards nicht sicher, aber wenn ich mich richtig erinnere, wird den App-Gruppen eine Team-ID vorangestellt
Santa Claus
73

Freigeben von NSUserDefaults-Daten zwischen mehreren Apps

Um gemeinsame Standardeinstellungen zwischen einer App und einer Erweiterung oder zwischen zwei Apps zu erhalten, müssen Sie in Ihren Einstellungen mithilfe der folgenden Schritte eine App-Gruppe hinzufügen:

  1. Klicken Sie im Projektnavigator auf die Datei * .xcodeproj (sollte oben sein).
  2. Suchen Sie rechts im Projektnavigator nach Projekt und Ziele. Klicken Sie unter Ziele auf Ihr primäres Ziel (sollte das erste sein, was unter Ziele angezeigt wird).
  3. Klicken Sie oben auf die Registerkarte Funktionen.
  4. Klicken Sie im Abschnitt App-Gruppen auf den Schalter rechts, um App-Gruppen einzuschalten.
  5. Klicken Sie auf die Schaltfläche + und fügen Sie eine App-Gruppe mit dem Namen group.com.company.myApp hinzu .
  6. Gehen Sie in Ihren anderen Apps zum selben Ort, und diese Gruppe sollte nun zur Auswahl verfügbar sein. Aktivieren Sie diese Gruppe für jede App, die diese freigegebenen Daten verwendet.

Hinweis: Wenn Sie das Apple Developer Portal (die Apple-Website, auf der alle Ihre Zertifikate, Kennungen, Geräte und Bereitstellungsprofile angezeigt werden) aufrufen und zu Kennungen> App-Gruppen wechseln, sollte diese neue App-Gruppe angezeigt werden.

So speichern Sie Daten:

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

So rufen Sie Daten ab:

var userDefaults = NSUserDefaults(suiteName: "group.com.company.myApp")
if let testUserId = userDefaults?.objectForKey("userId") as? String {
  print("User Id: \(testUserId)")
}
TenaciousJay
quelle
2
Vielen Dank! Ich musste ein wenig in der Dokumentation suchen, um herauszufinden, wie das geht, und ich dachte, andere könnten die Schritte, die ich unternommen habe, zu schätzen wissen.
TenaciousJay
Danke für die ausführliche Beschreibung ...! Müssen wir ein Zertifikat aus dem Apple Developer Portal (der Apple-Website, auf der alle Ihre Zertifikate, Kennungen, Geräte und Bereitstellungsprofile angezeigt werden) erstellen, um diese Gruppe zu aktivieren? das gleiche wie Push-Benachrichtigung.?
Arbaz Shaikh
Wenn Sie Schritt 5 ausführen, sollte die App-Gruppe zum Apple Developer Portal hinzugefügt werden. Sie sollten nicht direkt zum Developer Portal gehen müssen, um sie hinzuzufügen. Nachdem Sie Schritt 5 ausgeführt haben, können Sie zum Portal gehen und sehen, dass es es für Sie erstellt haben sollte.
TenaciousJay
@TenaciousJay Hervorragende Antwort. Ich möchte nur hinzufügen Wenn Sie die App über die func-Anwendung starten möchten (App: UIApplication, openURL-URL: NSURL, Optionen: [String: AnyObject]) -> Bool
Taimur Ajmal
gute Antwort. danke @TenaciousJay. Ich versuche, eine Variable und ihren Wert von AppB in AppA abzurufen. Wie würde ich das tun? Wenn zum Beispiel "riderCancelledRequest = true" in AppB, wie würde ich dies in AppA abrufen?
LizG
37

Anwendungsgruppen sind nach meiner Interpretation der vorhandenen Dokumentation in erster Linie für Erweiterungen gedacht, insbesondere für Widgets. Widgets sind ein eigenes Anwendungspaket, das mit Ihrer App koexistiert. Da es sich um eine separate Anwendung handelt und daher über eine eigene Sandbox verfügt, müssen Sie App-Gruppen verwenden, um Dateien freizugeben.

Nach einigem Durchsuchen der Header fand ich die benötigte API, wurde aber tatsächlich als Teil von iOS 7 eingefügt.

NSFileManagerEs gibt eine Methode, containerURLForSecurityApplicationGroupIdentifier:mit der Sie die Kennung übergeben können, die Sie beim Aktivieren von App-Gruppen für Ihre Apps erstellt haben:

NSURL *containerURL = [[NSFileManager defaultManager] 
           containerURLForSecurityApplicationGroupIdentifier:@"group.com.company.app"];
Wayne Hartman
quelle
Danke, ich glaube, Sie haben Recht mit der Erweiterbarkeit. Ich bin etwas zweifelhafter in Bezug auf diese iOS 7-Methode. Sie scheint mir ziemlich statisch zu sein. IOS 8 hat echte Interaktionen und Kommunikation zwischen Apps eingeführt.
Streem
@Justafinger Diese iOS 7-Methode dient nur zum Erstellen einer URL zum Schreiben und Lesen von Daten zwischen den freigegebenen Anwendungen. Diese spezielle Methode ist nur für Widgets wirklich nützlich (soweit ich das sehe), aber nicht für andere Erweiterungen.
Wayne Hartman
Ich glaube, Apple wollte dies in iOS 8 einfacher machen, ohne programmgesteuert einen Container erstellen und benutzerdefinierte Dateien freigeben zu müssen. In der Dokumentation wird angegeben , dass Sie Daten mithilfe von NSUserDefault freigeben können sollten. Ich vermisse wohl etwas, weil das bei mir nicht funktioniert.
Streem
@ Justafinger Ich konnte auch nicht NSUserDefaultszur Arbeit kommen. Ich kreide bis zu Beta 1 Bug.
Wayne Hartman
@WayneHartman Es gibt eine Problemumgehung für die NSUserDefaultsDatenbank. Siehe meine Antwort.
Weihnachtsmann
6

Eine wichtige Falle, die ich heute angezapft habe, ist die folgende:

In vielen Projekten habe ich ein einzelnes App-Ziel gesehen und für jede Konfiguration dieses Ziels unterschiedliche Bundle-IDs festgelegt. Hier wird es chaotisch. Die Entwickler wollten eine Debug-App für die Debug-Konfiguration und eine Produktions-App für das Release-Ziel erstellen.

In diesem Fall verwenden beide Apps dieselben NSUserDefaults, wenn sie wie folgt eingerichtet werden

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

Dies verursacht vielerorts Probleme:

  1. Stellen Sie sich vor, Sie setzen JA für einen Schlüssel, wenn dem Benutzer ein spezieller App-Intro-Bildschirm angezeigt wurde. Die andere App liest jetzt ebenfalls JA und zeigt das Intro nicht an.
  2. Ja, einige Apps speichern oAuth-Token auch in ihren Benutzerstandards. Wie auch immer ... Abhängig von der Implementierung erkennt die App, dass ein Token vorhanden ist, und beginnt mit dem Abrufen von Daten mit dem falschen Token. Die Wahrscheinlichkeit ist hoch, dass dies mit seltsamen Fehlern fehlschlägt.

Die Lösung für dieses Problem besteht im Allgemeinen darin, den Standardschlüsseln die aktuell erstellte Konfiguration voranzustellen. Sie können die Konfiguration zur Laufzeit leicht erkennen, indem Sie verschiedene Bundle-IDs für Ihre Konfigurationen festlegen. Dann lesen Sie einfach die Bundle-ID von NSBundle.mainBundle(). Wenn Sie die gleichen Bundle-IDs haben, müssen Sie verschiedene Präprozessor-Makros wie festlegen

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

In Swift wird es fast gleich aussehen:

#if DEBUG
  let configuration = "debug"
#elseif RELEASE
  let configuration = "release"
#endif
blackjacx
quelle
8
Ihre Probleme bestehen, weil Sie alle Ihre Daten in einem gemeinsam genutzten UserDefaults mischen. Sie sollten NSUserDefaults.standardUserDefaults()für Daten verwenden, die nicht freigegeben werden sollen.
Daniel
2

Lagern

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