Exposer le conteneur ubiquitaire d'une application au lecteur iCloud dans iOS 8

je développe une application compatible iCloud où les utilisateurs pourront importer et exporter des fichiers via le lecteur iCloud. Lors de la navigation sur le lecteur iCloud, soit en utilisant le UIDocumentPickerViewController (iOS 8) ou le Finder (OS X Yosemite), je peux voir des répertoires créés/possédés par d'autres applications compatibles iCloud Drive, telles que Automator, Keynote, ou TextEdit.

je veux que notre application expose son répertoire ubiquitaire de documents dans iCloud Drive, aussi, mais n'ont pas encore été en mesure de le comprendre. Au sein de certains susmentionnés apps' Info.plist fichiers, 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 pas trouvé d'autres documents sur le sujet plus large. Modifier/Remarque: Bien qu'il ne contient pas la réponse à mes questions, le Document Sélecteur De Guide De Programmation est une ressource utile.

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

  • pour les applications tierces, les conteneurs iCloud sont construits de cette façon:iCloud.$(CFBundleIdentifier). Je ne sais pas pourquoi TextEdit n'utilise que l'identifiant du paquet pur, mais pour notre identifiant, j'ai essayé les deux approches, c'est-à-dire avec et sans iCloud. préfixe. J'ai aussi reconnu que vous devez coder l'identifiant du paquet (i.e., n'utilisez pas iCloud.$(CFBundleIdentifier)) comme seules les valeurs de PLIST semblent être résolues au moment de la construction, mais pas les touches.

  • j'ai ajouté un sous-répertoire par programmation (<containerPath>/Documents) si le conteneur n'est pas vide. Cependant, cela ne devrait pas avoir d'importance, car tous les répertoires des autres applications étaient vides au début.

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

  • iCloud est configuré correctement et je peux programmer regarder dans le conteneur ubiquity en utilisant L'URL renvoyée par [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];.

  • je suis connecté à un compte iCloud où le lecteur iCloud est activé. Je peux voir le contenu de mon lecteur iCloud dans le UIDocumentPickerViewController.

  • j'utilise le simulateur iOS 8 beta 5 (et Yosemite beta 5 pour voir le répertoire d'entraînement iCloud sur Mac) (Modifier/Remarque: ceci s'applique également à beta 6)

voici à quoi ressemble mon fichier de versements (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é ceci en utilisant L'interface utilisateur de Xcode dans la section capacités. Je ne comprends pas pourquoi la dernière touche n'a pas d'entrée, mais en ajoutant <string>iCloud.$(CFBundleIdentifier)</string> n'aide pas. Au lieu de cela, il fait Xcode se plaindre dans les capacités UI, donc je l'ai enlevé. Modifier/Remarque: dans Xcode beta 6, cela a été corrigé, i.e., l'identifiant du conteneur ubiquity doit être défini et Xcode peut le corriger pour vous.

Questions Originales:... est-ce un bug? Faire il ne fonctionne pas encore? Suis-je le fais mal? Je n'ai pas trouvé de problème connu dans les notes de publication.

Edit:

deux autres choses que j'ai essayées:

  • ajouter le (optionnel) NSUbiquitousContainerName (+ valeur) pour le conteneur dictionnaire spécifique, comme suggéré par Erikmitk.

  • en ajoutant seulement le NSUbiquitousContainerIsDocumentScopePublic clé/valeur à la PLIST racine dictionnaire plutôt que le contenant dictionnaire spécifique, comme cela se fait dans l'un des WWDC exemples d'applications (cherchez NewBox).

25
demandé sur hagi 2014-08-08 16:36:04

11 réponses

quand vous avez édité l'Info.plist, peut-être que tu as oublié d'augmenter le numéro de version du paquet? C'est une exigence que par WWDC session #234.

13
répondu roop 2014-08-15 15:02:41

j'éprouvais un problème semblable avec ma demande. J'ai été capable de faire ce travail de la façon suivante:

  1. Ajouter NSUbiquitousContainers mon Info.plist fichier selon la documentation ici https://developer.apple.com/library/prerelease/ios/documentation/General/Conceptual/ExtensibilityPG/FileProvider.html. Voici le code correspondant:

    <dict>
        <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>
    
  2. Important! j'ai ensuite changé le ci-dessus NSUbiquitousContainerSupportedFolderLevels valeur de la chaîne de caractères de AnyOne

    <key>NSUbiquitousContainerSupportedFolderLevels</key>
    <string>One</string>
    
  3. ensuite, et enfin, j'ai dû changer CFBundleVersion vers une version plus haute. J'ai aussi frappé l' CFBundleShortVersionString pour une nouvelle version.

construit et exécuté et après cela, le dossier avec l'icône de mes applications est apparu correctement dans le lecteur iCloud! Espérons que cette aide!

11
répondu Aaron Wright 2018-01-12 08:37:59

Le hic, c'est d'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 en changeant l'une des entrées de la liste respective) afin d'initialiser le répertoire. Je pense que cette étape doit être combinée avec une augmentation du numéro de version du paquet, comme suggéré dans la réponse de roop.

j'ai remarqué que ma question pouvait prêter à confusion à cet égard, car j'ai mentionné le fait de pouvoir examiner les répertoire de documents * par programmation À l'aide de l'API en question. Cependant, j'ai retiré ce code de l'application plus tard, peut-être avant d'avoir le reste de la configuration. Je ne vais pas écrire dans le répertoire des documents directement, seulement par L'intermédiaire du collecteur de documents. Par conséquent, il n'a pas été nécessaire d'obtenir l'URL.

si vous avez juste besoin d'un sélectionneur de documents pour lire/stocker des fichiers à partir de/dans les répertoires de documents d'iCloud Drive ou d'autres applications, il n'est pas nécessaire d'appeler URLForUbiquityContainerIdentifier:. Seulement si vous voulez votre application pour avoir son propre conteneur ubiquity (et potentiellement l'exposer dans iCloud Drive et le document Picker), les étapes mentionnées dans le post original et l'appel à URLForUbiquityContainerIdentifier: sont nécessaires.

*en mentionnant le répertoire des documents, je me réfère toujours à celui du conteneur ubiquity, pas au local.

7
répondu hagi 2014-09-02 08:40:05

Il semble, la modification de l' CFBundleVersion va le laisser travailler.

je pense que vous pouvez essayer. J'ai obtenu ce à partir de Forums De Développeurs Apple.

espérons que cela fonctionne pour vous.

3
répondu Jim Tsai 2016-10-03 08:33:07

dans mon cas (Xcode 7 et iOS 9), la seule chose qui a fait que cela fonctionne, après plusieurs essais, était juste utiliser un nouvel identificateur de paquet (vous n'avez pas à changer l'Identificateur de conteneur cloud, juste être sûr de sélectionner le conteneur que vous voulez utiliser dans le centre de membre de développeur D'Apple et de spécifier dans Xcode un conteneur personnalisé au lieu de la valeur par défaut).

en fait, cela signifie la première fois que vous lancez votre application, la section NSUbiquitousContainers de l'info.plist doit être réglé jusqu'. Si tu le mets après comme une deuxième étape, ça ne marchera pas...

2
répondu Yet Another Code Maker 2015-09-26 20:05:47

après avoir travaillé avec ça toute la matinée, lu tous les billets, fait tous les changements, la chose clé qui a finalement fonctionné pour moi était, comme Encore Un Autre Créateur De Code a déclaré, la modification de l'ID de l'offre. Je pense qu'une fois qu'il a créé un conteneur pour un paquet, vous ne pouvez pas revenir en arrière et changer la visibilité de celui-ci pour le faire apparaître dans Finder. J'avais essayé toutes les informations différentes.valeurs plist mais rien n'a fonctionné jusqu'à ce que je change pour un nouveau nom de paquet et forcé le système à créer un nouveau un. Au fait, je ne l'ai vu nulle part, mais le nom du paquet, le nom du container Nsubiquitous et le nom du container Nsubiquitous peuvent tous être différents - ce que j'ai fait dans mon cas. Après avoir passé tant de temps sur ce sujet, j'ai pensé que je pourrais aller de l'avant et mettre un exemple d'application simple sur GitHub au cas où quelqu'un aurait encore des problèmes à déboguer leur dossier iCloud apparaissant dans Finder - vous pouvez le trouver ici. Toutes les étapes nécessaires sont décrites dans README.

2
répondu profRic 2017-03-12 19:55:25

Je N'ai pas pu trouver de documentation, mais par tâtonnements, j'ai trouvé que:

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

vous donne l'URL de base du lecteur tel que vu dans le picker. En utilisant cette URL de base, j'ai pu sauvegarder des fichiers dans mon application et les voir sur le lecteur iCloud dans Yosemite.

Modifier 14.8.14

j'ai essayé votre plist paramètres:

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

dans mon petit test d'application "docTest" il expose en effet le répertoire des Documents vides dans Yosemite et dans le document sélecteur.

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

1
répondu Ryan C. Spring 2014-08-14 20:31:35

L' .plist de l'inscription 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 montrer.

0
répondu Erik 2014-08-08 13:07:26

le même problème s'est produit pour mon application OSX.

il semble que la mise en place de containers Nsubiquitous ne fonctionne qu'au moment de la création des conteneurs iCloud. Alors j'ai essayé avec New Apple ID (pour la préparation de l'environnement propre iCloud), il devient de travailler.

0
répondu nyamakawa 2014-09-02 04:06:28

je voulais juste souligner une des découvertes de L'OP qui l'a corrigé pour moi:

j'ai aussi reconnu que vous devez coder dur l'identifiant du paquet (i.e., n'utilisez pas iCloud.$(CFBundleIdentifier)) comme seules les valeurs de PLIST semblent être résolues au moment de la construction, mais pas les clés.

Vous avez besoin de code dur l'ID du paquet. Mettez également à jour la version.

(Je n'ai pas remarqué cela dans la question jusqu'à ce que j'ai passé en revue toutes les réponses).

0
répondu jasongregori 2016-04-28 16:42:12

je sais qu'il s'agit d'un vieux fil, mais juste au cas où quelqu'un tomberait dans le même problème: la seule façon pour moi d'obtenir mon dossier de conteneur pour être visible dans le lecteur iCloud (après avoir essayé toutes les suggestions ci-dessus) était de faire que mon application crée un fichier temporaire dans le dossier Documents. Dès que j'ai fait cela, le dossier conteneur (et le fichier que j'ai créé) s'est affiché sur mon Mac. Si c'est vraiment le cas que je dois créer un fichier pour faire de ce dossier visible alors ce serait un peu ennuyeux à cause de mon application est un lecture seule application (ne lit que les fichiers ajoutés par l'utilisateur pour le Dossier Conteneur). Le Dossier Conteneur doit être visible dès que l'application est lancée pour la première fois. Je suppose que je vais devoir détecter le premier lancement.

0
répondu HLX74000 2018-01-05 17:32:51