it-swarm.com.de

Den allgegenwärtigen Container einer App in iCloud Drive unter iOS 8 verfügbar machen

Ich entwickle eine iCloud-fähige App, mit der Benutzer Dateien über iCloud Drive importieren und exportieren können. Beim Durchsuchen des iCloud-Laufwerks, entweder mit der UIDocumentPickerViewController (iOS 8) oder dem Finder (OS X Yosemite), kann ich Verzeichnisse sehen, die von anderen iCloud-Drive-fähigen Apps erstellt wurden oder deren Eigentümer ist, wie Automator, Keynote oder TextEdit.

Ich möchte, dass unsere App auch das allgegenwärtige Dokumentenverzeichnis in iCloud Drive verfügbar macht, bisher aber noch nicht herausgefunden hat. In einigen der Info.plist -Dateien der Apps habe ich diesen Schlüssel entdeckt:

<key>NSUbiquitousContainers</key>
<dict>
    <key>com.Apple.TextEdit</key>
    <dict>
        <key>NSUbiquitousContainerIsDocumentScopePublic</key>
        <true/>
        <key>NSUbiquitousContainerSupportedFolderLevels</key>
        <string>Any</string>
    </dict>
</dict>

Diese Schlüssel sind ebenfalls dokumentiert hier , aber ich habe keine weitere Dokumentation zu diesem Thema gefunden. Edit/Hinweis: Obwohl es keine Antwort auf meine Fragen enthält, ist Document Picker Programming Guide eine hilfreiche Ressource.

Ich habe versucht, die oben genannten Schlüssel/Werte zu unserer App hinzuzufügen, habe aber keinen Effekt gesehen. Dinge, die mir aufgefallen sind/ausprobiert haben:

  • Für Apps von Drittanbietern werden iCloud-Container folgendermaßen erstellt: iCloud.$(CFBundleIdentifier). Ich bin nicht sicher, warum TextEdit nur die reine Paketkennung verwendet, aber für unsere Kennung habe ich beide Ansätze ausprobiert, d. H. Mit und ohne das Präfix iCloud.. Ich habe auch erkannt, dass Sie die Bündel-ID hart codieren müssen (d. H. Verwenden Sie nicht iCloud.$(CFBundleIdentifier)), da nur die Werte der PLIST zur Build-Zeit aufgelöst zu sein scheinen, nicht jedoch die Schlüssel.

  • Ich habe ein Unterverzeichnis programmgesteuert hinzugefügt (zu <containerPath>/Documents), damit der Container nicht leer ist. Dies sollte jedoch keine Rolle spielen, da auch alle Verzeichnisse der anderen Apps anfangs leer waren.

  • Einige Apple-Apps, die in iCloud Drive angezeigt werden, enthalten diese Einträge nicht in Info.plist, z. B. Zahlen und Seiten.

  • iCloud ist korrekt eingerichtet, und ich kann den Ubiquity-Container mithilfe der von [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil]; zurückgegebenen URL programmgesteuert nachschlagen.

  • Ich bin bei einem iCloud-Konto angemeldet, auf dem iCloud Drive aktiviert ist. Ich kann meinen iCloud Drive-Inhalt in der UIDocumentPickerViewController sehen.

  • Ich verwende den iOS 8 Beta 5-Simulator (und Yosemite Beta 5, um das Verzeichnis iCloud Drive auf dem Mac anzuzeigen) (Edit/Hinweis: Dies gilt auch für Beta 6).

So sieht meine Entitlements-Datei aus (nur relevante Teile)

<key>com.Apple.developer.icloud-container-identifiers</key>
<array>
    <string>iCloud.$(CFBundleIdentifier)</string>
</array>
<key>com.Apple.developer.icloud-services</key>
<array>
    <string>CloudDocuments</string>
</array>
<key>com.Apple.developer.ubiquity-container-identifiers</key>
<array/>

Ich habe dies mit der Xcode-Benutzeroberfläche im Abschnitt "Funktionen" eingerichtet. Ich kann nicht verstehen, warum der letzte Schlüssel keinen Eintrag hat, aber das Hinzufügen von <string>iCloud.$(CFBundleIdentifier)</string> hilft nicht. Stattdessen wird Xcode in der Capabilities-Benutzeroberfläche beschwert, sodass ich ihn entfernt habe. Edit/Hinweis: In Xcode Beta 6 wurde dieses Problem behoben, d. H., Die Ubiquity-Container-ID muss festgelegt werden, und Xcode kann dies für Sie beheben.

Ursprüngliche Fragen: Also ... ist es ein Fehler? Funktioniert es noch nicht? Mache ich es falsch? In den Versionshinweisen konnte kein bekanntes Problem gefunden werden.

Bearbeiten:

Zwei weitere Dinge, die ich ausprobiert habe:

  • Hinzufügen des (optionalen) NSUbiquitousContainerName-Schlüssels (+ Wert) zu dem container-spezifischen Wörterbuch, wie von Erikmitk vorgeschlagen.

  • Hinzufügen nur des Schlüssels/Werts NSUbiquitousContainerIsDocumentScopePublic zum PLIST-Root-Wörterbuch anstelle des container-spezifischen Wörterbuchs, wie in einer der WWDC-Beispiel-Apps (Suche nach NewBox).

26
hagi

Der Haken beim Aufruf von [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil]; (oder mit einer anderen Container-ID, falls dies nicht die Standardeinstellung ist) mindestens einmal (nicht pro Start, aber vermutlich pro Version oder beim Ändern eines der entsprechenden PLIST-Einträge), um das Verzeichnis zu initialisieren. Ich denke, dieser Schritt muss mit einer Erhöhung der Paketversionsnummer kombiniert werden, wie in der Antwort von roop vorgeschlagen.

Ich stelle fest, dass meine Frage in dieser Hinsicht verwirrend war, da ich bereits erwähnt habe, dass ich das Dokumentenverzeichnis * mit der fraglichen API programmgesteuert einsehen kann. Ich habe den Code jedoch später aus der App entfernt, möglicherweise bevor der Rest des Setups richtig war. Ich schreibe nicht direkt in das Dokumentenverzeichnis, sondern nur über die Dokumentauswahl. Daher war es nicht nötig, die URL abzurufen.

Wenn Sie lediglich einen Document Picker zum Lesen/Speichern von Dateien aus/in iCloud Drive oder den Dokumentverzeichnissen anderer Apps benötigen, müssen Sie URLForUbiquityContainerIdentifier: nicht aufrufen. Nur wenn Sie möchten, dass Ihre App über einen eigenen Ubiquity-Container verfügt (und diesen möglicherweise in iCloud Drive und Document Picker verfügbar macht), sind die im ursprünglichen Beitrag genannten Schritte und der Aufruf von URLForUbiquityContainerIdentifier: erforderlich.

* Wenn ich das Dokumentenverzeichnis erwähne, beziehe ich mich immer auf das Verzeichnis im Ubiquity-Container, nicht auf das lokale.

7
hagi

Ich hatte ein ähnliches Problem mit meiner Bewerbung. Ich konnte diese Arbeit machen, indem ich Folgendes tat:

  1. Fügen Sie die Einstellung NSUbiquitousContainers meiner Info.plist-Datei entsprechend der Dokumentation hier hinzu https://developer.Apple.com/library/prerelease/ios/documentation/General/Conceptual/ExtensibilityPG/FileProvider.html . Hier ist der entsprechende Code:

    <dict>
        <!-- ... other top-level Info.plist settings ... -->
        <key>NSUbiquitousContainers</key>
        <dict>
            <key>iCloud.com.example.MyApp</key>
            <dict>
                <key>NSUbiquitousContainerIsDocumentScopePublic</key>
                <true/>
                <key>NSUbiquitousContainerSupportedFolderLevels</key>
                <string>Any</string>
                <key>NSUbiquitousContainerName</key>
                <string>MyApp</string>
            </dict>
        </dict>
    </dict>
    
  2. Wichtig! Ich änderte dann den obigen Wert der NSUbiquitousContainerSupportedFolderLevels-Zeichenfolge von Any in One.

    <key>NSUbiquitousContainerSupportedFolderLevels</key>
    <string>One</string>
    
  3. Als nächstes und zuletzt musste ich CFBundleVersion auf eine höhere Version umstellen. Ich habe auch die CFBundleShortVersionString auf eine neue Version gestoßen.

Errichtet und ausgeführt und danach wurde der Ordner mit meinem Anwendungssymbol ordnungsgemäß in iCloud Drive angezeigt! Hoffe das hilft!

14
Aaron Wright

Wenn Sie die Info.plist bearbeitet haben, haben Sie vielleicht vergessen, die Versionsnummer des Pakets zu erhöhen. Dies ist eine Voraussetzung gemäß WWDC-Sitzung # 234 .

13
roop

Es scheint, dass das Ändern von CFBundleVersion es funktionieren lässt.

Ich denke, du kannst es versuchen. Ich habe dies von Apple Developer Forums erhalten.

Hoffe diese Arbeit für dich.

3
Jim Tsai

Nachdem ich den ganzen Morgen damit herumgespielt hatte, alle Beiträge gelesen und alle Änderungen vorgenommen hatte, war das Wichtigste, was schließlich für mich funktionierte, wie Yet Another Code Maker feststellte und die Bündel-ID änderte. Ich denke, sobald ein Container für ein Bundle erstellt wurde, können Sie nicht mehr die Sichtbarkeit ändern, damit er im Finder angezeigt wird. Ich hatte alle verschiedenen info.plist-Werte ausprobiert, aber nichts funktionierte, bis ich zu einem neuen Paketnamen wechselte und das System zwang, einen neuen zu erstellen. Ich habe das übrigens nirgendwo gesehen, aber der Name des Bundles, der Name des NSUbiquitousContainer und der NSUbiquitousContainerName können alle unterschiedlich sein - was ich in meinem Fall getan habe. Nachdem ich so viel Zeit damit verbracht hatte, dachte ich, ich würde eine einfache Beispiel-App auf GitHub veröffentlichen, falls noch Probleme mit dem Debuggen ihres iCloud-Ordners im Finder auftreten sollte - Sie finden ihn hier . Alle erforderlichen Schritte sind in der LIESMICH beschrieben.

2
profRic

In meinem Fall (Xcode 7 und iOS 9) war das einzige, was nach mehreren Versuchen dazu führte, dass nur eine neue Bündel-ID verwendet wurde (Sie müssen die Cloud-Container-ID nicht ändern Sie möchten im Apple Developer Member Center verwenden und in Xcode einen benutzerdefinierten Container anstelle des Standardcontainers angeben.

Das heißt, wenn Sie Ihre Anwendung zum ersten Mal ausführen, muss der Abschnitt NSUbiquitousContainers der info.plist eingerichtet werden. Wenn Sie es anschließend als zweiten Schritt einstellen, funktioniert es nicht ...

Ich konnte keine Dokumentation finden, aber Versuch und Irrtum habe ich festgestellt:

[[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:@"com.Apple.CloudDocs"]; 

Gibt die Basis-URL für das Laufwerk an, wie in der Auswahlliste angezeigt. Mit dieser Basis-URL konnte ich Dateien in meiner App speichern und auf dem iCloud-Laufwerk in Yosemite anzeigen.

Bearbeiten 14.8.14

Ich habe deine Plist-Einstellungen ausprobiert:

<key>NSUbiquitousContainers</key>
<dict>
    <key>iCloud.net.redacted.docTest</key>
    <dict>
        <key>NSUbiquitousContainerIsDocumentScopePublic</key>
        <true/>
        <key>NSUbiquitousContainerSupportedFolderLevels</key>
        <string>Any</string>
    </dict>
</dict>

In meiner kleinen Wegwerftest-App "docTest" macht es tatsächlich das leere Documents-Verzeichnis in Yosemite und im Document Picker verfügbar. 

Screenshot http://spring-appstudio.com/picker-view.png

1
Ryan C. Spring

Ich weiß, dass dies ein alter Thread ist, aber nur für den Fall, dass jemand auf das gleiche Problem stößt: Um meinen Containerordner in iCloud Drive sichtbar zu machen (nachdem ich alle oben genannten Vorschläge ausprobiert hatte), musste meine App eine temporäre Datei erstellen im Ordner Dokumente. Sobald ich das getan habe, erschien der Containerordner (und die von mir erstellte Datei) auf meinem Mac. Wenn dies wirklich der Fall ist, dass ich eine Datei erstellen muss, um diesen Ordner sichtbar zu machen, wäre dies etwas ärgerlich, da meine App eine schreibgeschützte App ist (nur vom Benutzer zum Containerordner hinzugefügte Dateien liest). Der Containerordner muss sichtbar sein, sobald die App zum ersten Mal gestartet wird. Ich denke, ich muss den ersten Start erkennen.

0
HLX74000

Der .plist-Eintrag auf dieser Dokumentationsseite hat einen zusätzlichen Eintrag:

<key>NSUbiquitousContainerName</key>
<string>MyApp</string>

Vielleicht verbietet der fehlende Name das Auftauchen.

0
Erik

Das gleiche Problem ist bei meiner OSX-App aufgetreten.

Es scheint, dass die Einstellung von NSUbiquitousContainers nur während der Erstellung der iCloud-Container funktioniert. Also habe ich mit neuer Apple ID (zur Vorbereitung einer sauberen iCloud-Umgebung) versucht, es wird funktionieren.

0
nyamakawa

Ich wollte nur eine der Entdeckungen des OP hervorheben, die es für mich repariert haben:

Ich habe auch erkannt, dass Sie die Bündel-ID hart codieren müssen (d. H. Verwenden Sie iCloud.$(CFBundleIdentifier)) nicht, da nur die Werte der PLIST zur Build-Zeit aufgelöst zu sein scheinen, nicht jedoch die Schlüssel.

Sie müssen die Bundle-ID hart codieren. Aktualisieren Sie auch die Version.

(Ich habe das in der Frage nicht bemerkt, bis ich alle Antworten durchgegangen bin).

0
jasongregori