web-dev-qa-db-fra.com

Exposer le conteneur omniprésent d'une application à iCloud Drive dans iOS 8

Je développe une application compatible iCloud où les utilisateurs pourront importer et exporter des fichiers via iCloud Drive. Lorsque je navigue sur iCloud Drive, à l'aide de UIDocumentPickerViewController (iOS 8) ou du Finder (OS X Yosemite), je peux voir les répertoires créés par d'autres applications compatibles avec iCloud-Drive, telles que Automator, Keynote ou TextEdit.

Je souhaite que notre application expose également son répertoire de documents omniprésent dans iCloud Drive, mais je n’ai pas encore été en mesure de le comprendre. Dans certains fichiers Info.plist des applications susmentionnées, j'ai découvert cette clé:

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

Ces clés sont également documentées ici , mais je n’ai trouvé aucune autre documentation sur le sujet au sens large. Modifier/Remarque: Bien qu'il ne contienne pas de réponse à mes questions, le Guide de programmation du sélecteur de documents est une ressource utile.

J'ai essayé d'ajouter les clés/valeurs mentionnées ci-dessus à notre application mais je n'ai constaté aucun effet. Choses que j'ai remarquées/essayées:

  • Pour les applications tierces, les conteneurs iCloud sont construits de la manière suivante: iCloud.$(CFBundleIdentifier). Je ne suis pas sûr de savoir pourquoi TextEdit utilise uniquement l’identifiant de paquet pur, mais pour notre identifiant, j’ai essayé les deux approches, c’est-à-dire avec et sans le préfixe iCloud.. J'ai également reconnu que vous devez coder en dur l'identificateur de paquet (c'est-à-dire, n'utilisez pas iCloud.$(CFBundleIdentifier)) car seules les valeurs de la liste PLIST semblent être résolues au moment de la construction, mais pas les clés.

  • J'ai ajouté un sous-répertoire par programme (à <containerPath>/Documents) afin que le conteneur ne soit pas vide. Cependant, cela ne devrait pas avoir d'importance, car tous les répertoires des autres applications étaient vides au départ.

  • Certaines applications Apple qui apparaissent dans iCloud Drive n'ont pas ces entrées dans leur Info.plist, par exemple, Numbers and Pages.

  • iCloud est configuré correctement et je peux consulter par programme le conteneur d'ubiquité à l'aide de l'URL renvoyée par [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];.

  • Je suis connecté à un compte iCloud sur lequel iCloud Drive est activé. Je peux voir le contenu de mon lecteur iCloud dans la variable UIDocumentPickerViewController.

  • J'utilise le simulateur iOS 8 beta 5 (et Yosemite beta 5 pour afficher le répertoire d'iCloud Drive sur Mac) (Edit/Remarque: Ceci s'applique également à la version 6 bêta.)

Voici à quoi ressemble mon fichier Droits (parties pertinentes uniquement)

<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/>

J'ai configuré cela à l'aide de l'interface utilisateur de Xcode dans la section Capabilities. Je ne comprends pas pourquoi la dernière clé n'a pas d'entrée, mais ajouter <string>iCloud.$(CFBundleIdentifier)</string> n'aide pas. Au lieu de cela, Xcode se plaint dans l'interface utilisateur de Capabilities, je l'ai donc supprimé. Edit/Note: Dans Xcode beta 6, ceci a été corrigé, c'est-à-dire que l'identifiant du conteneur d'ubiquité doit être défini et que Xcode peut résoudre ce problème pour vous.

Questions originales: Alors ... est-ce un bug? Ça ne marche pas encore? Est-ce que je me trompe? Je ne pouvais pas trouver un problème connu dans les notes de publication.

Modifier:

Deux autres choses que j'ai essayées:

  • Ajout de la clé (facultative) NSUbiquitousContainerName (+ value) au dictionnaire propre au conteneur, comme suggéré par Erikmitk.

  • Ajoutez uniquement la clé/valeur NSUbiquitousContainerIsDocumentScopePublic au dictionnaire racine PLIST plutôt qu'au dictionnaire spécifique au conteneur, comme dans l'un des exemples d'application WWDC (recherchez NewBox).

26
hagi

Le problème consiste à appeler [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil]; (ou avec un autre identifiant de conteneur si ce n'est pas celui par défaut) au moins une fois (pas par lancement, mais probablement par version, ou lors de la modification d'une des entrées PLIST respectives) afin d'initialiser le répertoire. Je pense que cette étape doit être combinée à une augmentation du numéro de version du paquet, comme suggéré dans la réponse de roop.

Je remarque que ma question a peut-être été source de confusion à cet égard, car j’ai mentionné la possibilité d’examiner par programmation le répertoire * des documents à l’aide de l’API en question. Cependant, j'ai supprimé ce code de l'application plus tard, peut-être avant d'obtenir le reste de la configuration. Je ne vais pas écrire directement dans le répertoire de documents, mais uniquement via le sélecteur de documents. Par conséquent, il n'a pas été nécessaire d'obtenir l'URL.

Si vous avez simplement besoin d'un sélecteur de documents pour lire/stocker des fichiers à partir de/dans le répertoire de documents d'iCloud Drive ou d'autres applications, il n'est pas nécessaire d'appeler URLForUbiquityContainerIdentifier:. Si vous souhaitez que votre application ait son propre conteneur d'ubiquité (et l'expose éventuellement dans iCloud Drive et le sélecteur de documents), les étapes mentionnées dans le message d'origine et l'appel à URLForUbiquityContainerIdentifier: sont nécessaires.

* Lorsque je mentionne le répertoire de documents, je me réfère toujours à celui du conteneur d'ubiquité, pas à celui local.

7
hagi

Je rencontrais un problème similaire avec mon application. J'ai pu faire ce travail en procédant comme suit:

  1. Ajoutez le paramètre NSUbiquitousContainers à mon fichier Info.plist conformément à la documentation disponible ici https://developer.Apple.com/library/prerelease/ios/documentation/General/Conceptual/ExtensibilityPG/FileProvider.html . Voici le code pertinent:

    <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. Important! J'ai ensuite changé la valeur de chaîne NSUbiquitousContainerSupportedFolderLevels ci-dessus de Any à One

    <key>NSUbiquitousContainerSupportedFolderLevels</key>
    <string>One</string>
    
  3. Ensuite et dernier, j'ai dû changer CFBundleVersion en une version supérieure. J'ai également remplacé la CFBundleShortVersionString dans une nouvelle version.

Construit et exécuté et ensuite, le dossier avec l'icône de mes applications est apparu correctement dans iCloud Drive! J'espère que cela t'aides!

14
Aaron Wright

Lorsque vous avez édité Info.plist, vous avez peut-être oublié de modifier le numéro de version du paquet? Ceci est une exigence selon la session WWDC n ° 234 .

13
roop

Il semble que changer la CFBundleVersion le laissera fonctionner.

Je pense que vous pouvez l'essayer. Je l’ai reçu de Forums des développeurs Apple .

J'espère que cela fonctionnera pour vous.

3
Jim Tsai

Après avoir passé toute la matinée à lire, à lire tous les articles, à apporter les modifications, l’essentiel, pour moi, a été de changer, comme le disait Yet Another Code Maker, le changement de l’identifiant du paquet. Je pense qu'une fois que le conteneur a été créé pour un paquet, vous ne pouvez plus revenir en arrière et en modifier la visibilité pour qu'il apparaisse dans le Finder. J'avais essayé toutes les différentes valeurs info.plist, mais rien ne fonctionnait jusqu'à ce que je change de nom et que je sois contraint de créer un nouveau nom. En passant, je n’ai rien vu de tel, sauf le nom du bundle, le nom NSUbiquitousContainer et le NSUbiquitousContainerName peuvent tous être différents - c’est ce que j’ai fait dans mon cas. Après avoir passé beaucoup de temps là-dessus, je me suis dit que j'allais mettre en place un exemple d'application simple sur GitHub, au cas où quelqu'un aurait toujours des problèmes pour déboguer leur dossier iCloud dans le Finder - vous pouvez le trouver ici . Toutes les étapes requises sont décrites dans le README .

2
profRic

Dans mon cas (Xcode 7 et iOS 9), la seule chose qui a fonctionné, après plusieurs tentatives, a simplement été d'utiliser un nouvel identifiant de bundle (vous n'avez pas besoin de changer l'identifiant de conteneur cloud, assurez-vous simplement de sélectionner le conteneur vous souhaitez utiliser dans le centre des développeurs Apple et spécifier dans Xcode un conteneur personnalisé au lieu du conteneur par défaut).

En fait, cela signifie que lors de la première exécution de votre application, la section NSUbiquitousContainers de info.plist doit être configurée. Si vous le définissez ensuite, cela ne fonctionnera pas ...

2

Impossible de trouver de la documentation, mais des essais et des erreurs, j'ai trouvé que:

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

Vous donne l'URL de base du lecteur, comme indiqué dans le sélecteur. En utilisant cette URL de base, j'ai pu enregistrer des fichiers dans mon application et les voir sur le lecteur iCloud dans Yosemite.

Éditer 14.8.14

J'ai essayé vos réglages de plist:

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

Dans ma petite application de test jetable "docTest", elle expose effectivement le répertoire Documents vide dans Yosemite et dans le sélecteur de documents. 

Capture d'écran http://spring-appstudio.com/picker-view.png

1
Ryan C. Spring

Je sais que c'est un vieux fil de discussion, mais au cas où quelqu'un rencontrerait le même problème: le seul moyen pour que mon dossier Container soit visible dans iCloud Drive (après avoir essayé toutes les suggestions ci-dessus) était de laisser mon application créer un fichier temporaire. dans le dossier Documents. Dès que je l'ai fait, le dossier de conteneur (et le fichier que j'ai créé) est apparu sur mon Mac. Si c'est vraiment le cas, je dois créer un fichier pour rendre ce dossier visible, ce serait un peu gênant car mon application est une application en lecture seule (ne lit que les fichiers ajoutés par l'utilisateur au dossier Container). Le dossier du conteneur doit être visible dès le lancement de l'application pour la première fois. Je suppose que je vais devoir détecter le premier lancement.

0
HLX74000

L'entrée .plist sur cette page de documentation a une entrée supplémentaire:

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

Peut-être que le nom manquant l'empêche de se présenter.

0
Erik

Le même problème est survenu dans mon application OSX.

Il semble que le paramètre NSUbiquitousContainers ne fonctionne que pendant la création des conteneurs iCloud. J'ai donc essayé avec un nouvel identifiant Apple (pour préparer un environnement iCloud propre), cela se passe au travail.

0
nyamakawa

Je voulais juste souligner l'une des découvertes du PO qui l'a corrigé:

J'ai également reconnu que vous devez coder en dur l'identificateur de paquet (c'est-à-dire, n'utilisez pas iCloud.$(CFBundleIdentifier)) car seules les valeurs de la liste PLIST semblent être résolues au moment de la construction, mais pas les clés.

Vous devez coder en dur l'identifiant du paquet. Mettez également à jour la version.

(Je n'ai pas remarqué cela dans la question avant d'avoir parcouru toutes les réponses).

0
jasongregori