Sélecteur de documents dans Xamarin.iOS

Le sélecteur de documents permet de partager des documents entre des applications. Ces documents peuvent être stockés dans iCloud ou dans le répertoire d’une autre application. Les documents sont partagés via l’ensemble d’extensions de fournisseur de documents que l’utilisateur a installés sur son appareil.

En raison de la difficulté de maintenir la synchronisation des documents entre les applications et le cloud, ils introduisent une certaine complexité nécessaire.

Spécifications

Les éléments suivants sont nécessaires pour effectuer les étapes présentées dans cet article :

  • Xcode 7 et iOS 8 ou version ultérieure : les API Xcode 7 et iOS 8 d’Apple doivent être installées et configurées sur l’ordinateur du développeur.
  • Visual Studio ou Visual Studio pour Mac : la dernière version de Visual Studio pour Mac doit être installée.
  • Appareil iOS : appareil iOS exécutant iOS 8 ou version ultérieure.

Modifications apportées à iCloud

Pour implémenter les nouvelles fonctionnalités du sélecteur de documents, les modifications suivantes ont été apportées au service iCloud d’Apple :

  • Le démon iCloud a été entièrement réécrit à l’aide de CloudKit.
  • Les fonctionnalités iCloud existantes ont été renommées iCloud Drive.
  • La prise en charge du système d’exploitation Microsoft Windows a été ajoutée à iCloud.
  • Un dossier iCloud a été ajouté dans mac OS Finder.
  • Les appareils iOS peuvent accéder au contenu du dossier iCloud mac OS.

Important

Apple fournit des outils pour aider les développeurs à gérer correctement le Règlement général sur la protection des données (RGPD) de l’Union européenne.

Qu’est-ce qu’un document ?

Lorsque vous faites référence à un document dans iCloud, il s’agit d’une entité autonome unique qui doit être perçue comme telle par l’utilisateur. Un utilisateur peut souhaiter modifier le document ou le partager avec d’autres utilisateurs (par e-mail, par exemple).

Il existe plusieurs types de fichiers que l’utilisateur reconnaît immédiatement en tant que documents, tels que les fichiers Pages, Keynote ou Numbers. Toutefois, iCloud ne se limite pas à ce concept. Par exemple, l’état d’un jeu (par exemple, une correspondance d’échecs) peut être traité comme un document et stocké dans iCloud. Ce fichier peut être transmis entre les appareils d’un utilisateur et lui permettre de récupérer un jeu là où il s’est arrêté sur un autre appareil.

Gestion des documents

Avant de vous plonger dans le code requis pour utiliser le sélecteur de documents avec Xamarin, cet article va aborder les meilleures pratiques d’utilisation des documents iCloud et plusieurs des modifications apportées aux API existantes requises pour prendre en charge le sélecteur de documents.

Utilisation de la coordination des fichiers

Étant donné qu’un fichier peut être modifié à partir de plusieurs emplacements différents, la coordination doit être utilisée pour éviter la perte de données.

Utilisation de la coordination des fichiers

Examinons l’illustration ci-dessus :

  1. Un appareil iOS utilisant la coordination de fichiers crée un document et l’enregistre dans le dossier iCloud.
  2. iCloud enregistre le fichier modifié dans le cloud pour la distribution sur chaque appareil.
  3. Un Mac joint voit le fichier modifié dans le dossier iCloud et utilise La coordination des fichiers pour copier les modifications apportées au fichier.
  4. Un appareil qui n’utilise pas La coordination des fichiers apporte une modification au fichier et l’enregistre dans le dossier iCloud. Ces modifications sont répliquées instantanément sur les autres appareils.

Supposons que l’appareil iOS d’origine ou le Mac a modifié le fichier, maintenant leurs modifications sont perdues et remplacées par la version du fichier à partir de l’appareil non coordonné. Pour éviter la perte de données, la coordination des fichiers est indispensable lors de l’utilisation de documents basés sur le cloud.

Utilisation d’UIDocument

UIDocument simplifie les choses (ou NSDocument sur macOS) en faisant tout le travail difficile pour le développeur. Il fournit une coordination de fichiers intégrée avec des files d’attente en arrière-plan pour empêcher le blocage de l’interface utilisateur de l’application.

UIDocument expose plusieurs API de haut niveau qui facilitent l’effort de développement d’une application Xamarin pour n’importe quelle utilisation requise par le développeur.

Le code suivant crée une sous-classe de UIDocument pour implémenter un document texte générique qui peut être utilisé pour stocker et récupérer du texte à partir d’iCloud :

using System;
using Foundation;
using UIKit;

namespace DocPicker
{
    public class GenericTextDocument : UIDocument
    {
        #region Private Variable Storage
        private NSString _dataModel;
        #endregion

        #region Computed Properties
        public string Contents {
            get { return _dataModel.ToString (); }
            set { _dataModel = new NSString(value); }
        }
        #endregion

        #region Constructors
        public GenericTextDocument (NSUrl url) : base (url)
        {
            // Set the default document text
            this.Contents = "";
        }

        public GenericTextDocument (NSUrl url, string contents) : base (url)
        {
            // Set the default document text
            this.Contents = contents;
        }
        #endregion

        #region Override Methods
        public override bool LoadFromContents (NSObject contents, string typeName, out NSError outError)
        {
            // Clear the error state
            outError = null;

            // Were any contents passed to the document?
            if (contents != null) {
                _dataModel = NSString.FromData( (NSData)contents, NSStringEncoding.UTF8 );
            }

            // Inform caller that the document has been modified
            RaiseDocumentModified (this);

            // Return success
            return true;
        }

        public override NSObject ContentsForType (string typeName, out NSError outError)
        {
            // Clear the error state
            outError = null;

            // Convert the contents to a NSData object and return it
            NSData docData = _dataModel.Encode(NSStringEncoding.UTF8);
            return docData;
        }
        #endregion

        #region Events
        public delegate void DocumentModifiedDelegate(GenericTextDocument document);
        public event DocumentModifiedDelegate DocumentModified;

        internal void RaiseDocumentModified(GenericTextDocument document) {
            // Inform caller
            if (this.DocumentModified != null) {
                this.DocumentModified (document);
            }
        }
        #endregion
    }
}

La GenericTextDocument classe présentée ci-dessus sera utilisée tout au long de cet article lors de l’utilisation du sélecteur de documents et des documents externes dans une application Xamarin.iOS 8.

Coordination de fichiers asynchrone

iOS 8 fournit plusieurs nouvelles fonctionnalités de coordination de fichiers asynchrones via les nouvelles API de coordination de fichiers. Avant iOS 8, toutes les API de coordination de fichiers existantes étaient totalement synchrones. Cela signifie que le développeur était responsable de l’implémentation de sa propre file d’attente en arrière-plan pour empêcher File Coordination de bloquer l’interface utilisateur de l’application.

La nouvelle NSFileAccessIntent classe contient une URL pointant vers le fichier et plusieurs options pour contrôler le type de coordination requis. Le code suivant illustre le déplacement d’un fichier d’un emplacement à un autre à l’aide d’intentions :

// Get source options
var srcURL = NSUrl.FromFilename ("FromFile.txt");
var srcIntent = NSFileAccessIntent.CreateReadingIntent (srcURL, NSFileCoordinatorReadingOptions.ForUploading);

// Get destination options
var dstURL = NSUrl.FromFilename ("ToFile.txt");
var dstIntent = NSFileAccessIntent.CreateReadingIntent (dstURL, NSFileCoordinatorReadingOptions.ForUploading);

// Create an array
var intents = new NSFileAccessIntent[] {
    srcIntent,
    dstIntent
};

// Initialize a file coordination with intents
var queue = new NSOperationQueue ();
var fileCoordinator = new NSFileCoordinator ();
fileCoordinator.CoordinateAccess (intents, queue, (err) => {
    // Was there an error?
    if (err!=null) {
        Console.WriteLine("Error: {0}",err.LocalizedDescription);
    }
});

Découverte et liste de documents

La façon de découvrir et de répertorier des documents consiste à utiliser les API existantes NSMetadataQuery . Cette section décrit les nouvelles fonctionnalités ajoutées à NSMetadataQuery qui rendent l’utilisation de Documents encore plus facile qu’auparavant.

Comportement existant

Avant iOS 8, NSMetadataQuery était lent à récupérer les modifications de fichiers locaux telles que : suppressions, créations et renommages.

Vue d’ensemble des modifications de fichier local NSMetadataQuery

Dans le diagramme ci-dessus :

  1. Pour les fichiers qui existent déjà dans le conteneur d’application, NSMetadataQuery les enregistrements existants NSMetadata sont précréés et mis en pool afin qu’ils soient instantanément disponibles pour l’application.
  2. L’application crée un fichier dans le conteneur d’application.
  3. Il y a un délai avant NSMetadataQuery de voir la modification du conteneur d’application et de créer l’enregistrement requis NSMetadata .

En raison du retard dans la création de l’enregistrement NSMetadata , l’application devait disposer de deux sources de données ouvertes : l’une pour les modifications de fichiers locaux et l’autre pour les modifications basées sur le cloud.

Couture

Dans iOS 8, NSMetadataQuery est plus facile à utiliser directement avec une nouvelle fonctionnalité appelée Stitching :

NSMetadataQuery avec une nouvelle fonctionnalité appelée Stitching

Utilisation de Stitching dans le diagramme ci-dessus :

  1. Comme auparavant, pour les fichiers qui existent déjà dans le conteneur d’application, NSMetadataQuery les enregistrements existants NSMetadata sont précréés et mis en file d’attente.
  2. L’application crée un fichier dans le conteneur d’application à l’aide de La coordination de fichiers.
  3. Un crochet dans le conteneur d’application voit la modification et appelle NSMetadataQuery pour créer l’enregistrement requis NSMetadata .
  4. L’enregistrement NSMetadata est créé directement après le fichier et est mis à la disposition de l’application.

En utilisant Stitching, l’application n’a plus besoin d’ouvrir une source de données pour surveiller les modifications de fichiers locaux et basés sur le cloud. L’application peut désormais s’appuyer directement sur NSMetadataQuery .

Important

L’assemblage fonctionne uniquement si l’application utilise la coordination de fichiers, comme indiqué dans la section ci-dessus. Si La coordination des fichiers n’est pas utilisée, les API par défaut sont le comportement antérieur à iOS 8 existant.

Nouvelles fonctionnalités de métadonnées iOS 8

Les nouvelles fonctionnalités suivantes ont été ajoutées à NSMetadataQuery iOS 8 :

  • NSMetatadataQuery peut maintenant répertorier les documents non locaux stockés dans le cloud.
  • De nouvelles API ont été ajoutées pour accéder aux informations de métadonnées sur les documents cloud.
  • Une nouvelle NSUrl_PromisedItems API permet d’accéder aux attributs de fichier des fichiers dont le contenu peut être disponible localement ou non.
  • Utilisez la GetPromisedItemResourceValue méthode pour obtenir des informations sur un fichier donné ou utilisez la GetPromisedItemResourceValues méthode pour obtenir des informations sur plusieurs fichiers à la fois.

Deux nouveaux indicateurs de coordination de fichiers ont été ajoutés pour traiter les métadonnées :

  • NSFileCoordinatorReadImmediatelyAvailableMetadataOnly
  • NSFileCoordinatorWriteContentIndependentMetadataOnly

Avec les indicateurs ci-dessus, le contenu du fichier document n’a pas besoin d’être disponible localement pour pouvoir être utilisé.

Le segment de code suivant montre comment utiliser NSMetadataQuery pour interroger l’existence d’un fichier spécifique et générer le fichier s’il n’existe pas :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Foundation;
using UIKit;
using ObjCRuntime;
using System.IO;

#region Static Properties
public const string TestFilename = "test.txt";
#endregion

#region Computed Properties
public bool HasiCloud { get; set; }
public bool CheckingForiCloud { get; set; }
public NSUrl iCloudUrl { get; set; }

public GenericTextDocument Document { get; set; }
public NSMetadataQuery Query { get; set; }
#endregion

#region Private Methods
private void FindDocument () {
    Console.WriteLine ("Finding Document...");

    // Create a new query and set it's scope
    Query = new NSMetadataQuery();
    Query.SearchScopes = new NSObject [] {
                NSMetadataQuery.UbiquitousDocumentsScope,
                NSMetadataQuery.UbiquitousDataScope,
                NSMetadataQuery.AccessibleUbiquitousExternalDocumentsScope
            };

    // Build a predicate to locate the file by name and attach it to the query
    var pred = NSPredicate.FromFormat ("%K == %@"
        , new NSObject[] {
            NSMetadataQuery.ItemFSNameKey
            , new NSString(TestFilename)});
    Query.Predicate = pred;

    // Register a notification for when the query returns
    NSNotificationCenter.DefaultCenter.AddObserver (this,
            new Selector("queryDidFinishGathering:"),             NSMetadataQuery.DidFinishGatheringNotification,
            Query);

    // Start looking for the file
    Query.StartQuery ();
    Console.WriteLine ("Querying: {0}", Query.IsGathering);
}

[Export("queryDidFinishGathering:")]
public void DidFinishGathering (NSNotification notification) {
    Console.WriteLine ("Finish Gathering Documents.");

    // Access the query and stop it from running
    var query = (NSMetadataQuery)notification.Object;
    query.DisableUpdates();
    query.StopQuery();

    // Release the notification
    NSNotificationCenter.DefaultCenter.RemoveObserver (this
        , NSMetadataQuery.DidFinishGatheringNotification
        , query);

    // Load the document that the query returned
    LoadDocument(query);
}

private void LoadDocument (NSMetadataQuery query) {
    Console.WriteLine ("Loading Document...");    

    // Take action based on the returned record count
    switch (query.ResultCount) {
    case 0:
        // Create a new document
        CreateNewDocument ();
        break;
    case 1:
        // Gain access to the url and create a new document from
        // that instance
        NSMetadataItem item = (NSMetadataItem)query.ResultAtIndex (0);
        var url = (NSUrl)item.ValueForAttribute (NSMetadataQuery.ItemURLKey);

        // Load the document
        OpenDocument (url);
        break;
    default:
        // There has been an issue
        Console.WriteLine ("Issue: More than one document found...");
        break;
    }
}
#endregion

#region Public Methods
public void OpenDocument(NSUrl url) {

    Console.WriteLine ("Attempting to open: {0}", url);
    Document = new GenericTextDocument (url);

    // Open the document
    Document.Open ( (success) => {
        if (success) {
            Console.WriteLine ("Document Opened");
        } else
            Console.WriteLine ("Failed to Open Document");
    });

    // Inform caller
    RaiseDocumentLoaded (Document);
}

public void CreateNewDocument() {
    // Create path to new file
    // var docsFolder = Environment.GetFolderPath (Environment.SpecialFolder.Personal);
    var docsFolder = Path.Combine(iCloudUrl.Path, "Documents");
    var docPath = Path.Combine (docsFolder, TestFilename);
    var ubiq = new NSUrl (docPath, false);

    // Create new document at path
    Console.WriteLine ("Creating Document at:" + ubiq.AbsoluteString);
    Document = new GenericTextDocument (ubiq);

    // Set the default value
    Document.Contents = "(default value)";

    // Save document to path
    Document.Save (Document.FileUrl, UIDocumentSaveOperation.ForCreating, (saveSuccess) => {
        Console.WriteLine ("Save completion:" + saveSuccess);
        if (saveSuccess) {
            Console.WriteLine ("Document Saved");
        } else {
            Console.WriteLine ("Unable to Save Document");
        }
    });

    // Inform caller
    RaiseDocumentLoaded (Document);
}

public bool SaveDocument() {
    bool successful = false;

    // Save document to path
    Document.Save (Document.FileUrl, UIDocumentSaveOperation.ForOverwriting, (saveSuccess) => {
        Console.WriteLine ("Save completion: " + saveSuccess);
        if (saveSuccess) {
            Console.WriteLine ("Document Saved");
            successful = true;
        } else {
            Console.WriteLine ("Unable to Save Document");
            successful=false;
        }
    });

    // Return results
    return successful;
}
#endregion

#region Events
public delegate void DocumentLoadedDelegate(GenericTextDocument document);
public event DocumentLoadedDelegate DocumentLoaded;

internal void RaiseDocumentLoaded(GenericTextDocument document) {
    // Inform caller
    if (this.DocumentLoaded != null) {
        this.DocumentLoaded (document);
    }
}
#endregion

Miniatures de document

Apple estime que la meilleure expérience utilisateur lors de la liste des documents d’une application est d’utiliser des préversions. Cela permet aux utilisateurs finaux d’identifier rapidement le document avec lequel ils souhaitent travailler.

Avant iOS 8, l’affichage des aperçus de documents nécessitait une implémentation personnalisée. Les nouveautés d’iOS 8 sont les attributs de système de fichiers qui permettent au développeur d’utiliser rapidement les miniatures de document.

Récupération des miniatures de document

En appelant les GetPromisedItemResourceValue méthodes ou GetPromisedItemResourceValues , NSUrl_PromisedItems l’API , un NSUrlThumbnailDictionary, est retourné. La seule clé actuellement dans ce dictionnaire est et NSThumbnial1024X1024SizeKey sa correspondance UIImage.

Enregistrement des miniatures de document

Le moyen le plus simple d’enregistrer une miniature consiste à utiliser UIDocument. En appelant la GetFileAttributesToWrite méthode du UIDocument et en définissant la miniature, elle est automatiquement enregistrée lorsque le fichier document est. Le démon iCloud voit cette modification et la propage à iCloud. Sur Mac OS X, les miniatures sont générées automatiquement pour le développeur par le plug-in Quick Look.

Avec les principes de base de l’utilisation de documents basés sur iCloud en place, ainsi que les modifications apportées à l’API existante, nous sommes prêts à implémenter le contrôleur d’affichage du sélecteur de documents dans une application mobile Xamarin iOS 8.

Activation d’iCloud dans Xamarin

Avant que le sélecteur de documents puisse être utilisé dans une application Xamarin.iOS, le support iCloud doit être activé à la fois dans votre application et via Apple.

Les étapes suivantes décrivent pas à pas le processus d’approvisionnement pour iCloud.

  1. Créez un conteneur iCloud.
  2. Créez un ID d’application qui contient le App Service iCloud.
  3. Créez un profil d’approvisionnement qui inclut cet ID d’application.

Le guide Utilisation des fonctionnalités décrit les deux premières étapes. Pour créer un profil d’approvisionnement, suivez les étapes décrites dans le guide Profil d’approvisionnement .

Les étapes suivantes décrivent pas à pas le processus de configuration de votre application pour iCloud :

Effectuez les actions suivantes :

  1. Ouvrez le projet dans Visual Studio pour Mac ou Visual Studio.

  2. Dans le Explorateur de solutions, cliquez avec le bouton droit sur le projet, puis sélectionnez Options.

  3. Dans la boîte de dialogue Options, sélectionnez Application iOS, vérifiez que l’identificateur de bundle correspond à celui qui a été défini dans l’ID d’application créé ci-dessus pour l’application.

  4. Sélectionnez Signature de bundle iOS, sélectionnez l’identité du développeur et le profil d’approvisionnement créé ci-dessus.

  5. Cliquez sur le bouton OK pour enregistrer les modifications et fermer la boîte de dialogue.

  6. Cliquez avec le bouton droit sur Entitlements.plist le Explorateur de solutions pour l’ouvrir dans l’éditeur.

    Important

    Dans Visual Studio, vous devrez peut-être ouvrir l’éditeur De droits en cliquant avec le bouton droit dessus, en sélectionnant Ouvrir avec... et en sélectionnant Éditeur de liste de propriétés

  7. Cochez Activer iCloud , documents iCloud , stockage clé-valeur et CloudKit .

  8. Vérifiez que le conteneur existe pour l’application (comme créé ci-dessus). Exemple : iCloud.com.your-company.AppName

  9. Enregistrez les modifications du fichier.

Pour plus d’informations sur les droits, consultez le guide Utilisation des droits .

Une fois la configuration ci-dessus en place, l’application peut désormais utiliser des documents basés sur le cloud et le nouveau contrôleur d’affichage sélecteur de documents.

Code d’installation courant

Avant de commencer à utiliser le contrôleur d’affichage du sélecteur de documents, un code d’installation standard est requis. Commencez par modifier le fichier de l’application AppDelegate.cs et faites-le ressembler à ce qui suit :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Foundation;
using UIKit;
using ObjCRuntime;
using System.IO;

namespace DocPicker
{

    [Register ("AppDelegate")]
    public partial class AppDelegate : UIApplicationDelegate
    {
        #region Static Properties
        public const string TestFilename = "test.txt";
        #endregion

        #region Computed Properties
        public override UIWindow Window { get; set; }
        public bool HasiCloud { get; set; }
        public bool CheckingForiCloud { get; set; }
        public NSUrl iCloudUrl { get; set; }

        public GenericTextDocument Document { get; set; }
        public NSMetadataQuery Query { get; set; }
        public NSData Bookmark { get; set; }
        #endregion

        #region Private Methods
        private void FindDocument () {
            Console.WriteLine ("Finding Document...");

            // Create a new query and set it's scope
            Query = new NSMetadataQuery();
            Query.SearchScopes = new NSObject [] {
                NSMetadataQuery.UbiquitousDocumentsScope,
                NSMetadataQuery.UbiquitousDataScope,
                NSMetadataQuery.AccessibleUbiquitousExternalDocumentsScope
            };

            // Build a predicate to locate the file by name and attach it to the query
            var pred = NSPredicate.FromFormat ("%K == %@",
                 new NSObject[] {NSMetadataQuery.ItemFSNameKey
                , new NSString(TestFilename)});
            Query.Predicate = pred;

            // Register a notification for when the query returns
            NSNotificationCenter.DefaultCenter.AddObserver (this
                , new Selector("queryDidFinishGathering:")
                , NSMetadataQuery.DidFinishGatheringNotification
                , Query);

            // Start looking for the file
            Query.StartQuery ();
            Console.WriteLine ("Querying: {0}", Query.IsGathering);
        }

        [Export("queryDidFinishGathering:")]
        public void DidFinishGathering (NSNotification notification) {
            Console.WriteLine ("Finish Gathering Documents.");

            // Access the query and stop it from running
            var query = (NSMetadataQuery)notification.Object;
            query.DisableUpdates();
            query.StopQuery();

            // Release the notification
            NSNotificationCenter.DefaultCenter.RemoveObserver (this
                , NSMetadataQuery.DidFinishGatheringNotification
                , query);

            // Load the document that the query returned
            LoadDocument(query);
        }

        private void LoadDocument (NSMetadataQuery query) {
            Console.WriteLine ("Loading Document...");    

            // Take action based on the returned record count
            switch (query.ResultCount) {
            case 0:
                // Create a new document
                CreateNewDocument ();
                break;
            case 1:
                // Gain access to the url and create a new document from
                // that instance
                NSMetadataItem item = (NSMetadataItem)query.ResultAtIndex (0);
                var url = (NSUrl)item.ValueForAttribute (NSMetadataQuery.ItemURLKey);

                // Load the document
                OpenDocument (url);
                break;
            default:
                // There has been an issue
                Console.WriteLine ("Issue: More than one document found...");
                break;
            }
        }
        #endregion

        #region Public Methods

        public void OpenDocument(NSUrl url) {

            Console.WriteLine ("Attempting to open: {0}", url);
            Document = new GenericTextDocument (url);

            // Open the document
            Document.Open ( (success) => {
                if (success) {
                    Console.WriteLine ("Document Opened");
                } else
                    Console.WriteLine ("Failed to Open Document");
            });

            // Inform caller
            RaiseDocumentLoaded (Document);
        }

        public void CreateNewDocument() {
            // Create path to new file
            // var docsFolder = Environment.GetFolderPath (Environment.SpecialFolder.Personal);
            var docsFolder = Path.Combine(iCloudUrl.Path, "Documents");
            var docPath = Path.Combine (docsFolder, TestFilename);
            var ubiq = new NSUrl (docPath, false);

            // Create new document at path
            Console.WriteLine ("Creating Document at:" + ubiq.AbsoluteString);
            Document = new GenericTextDocument (ubiq);

            // Set the default value
            Document.Contents = "(default value)";

            // Save document to path
            Document.Save (Document.FileUrl, UIDocumentSaveOperation.ForCreating, (saveSuccess) => {
                Console.WriteLine ("Save completion:" + saveSuccess);
                if (saveSuccess) {
                    Console.WriteLine ("Document Saved");
                } else {
                    Console.WriteLine ("Unable to Save Document");
                }
            });

            // Inform caller
            RaiseDocumentLoaded (Document);
        }

        /// <summary>
        /// Saves the document.
        /// </summary>
        /// <returns><c>true</c>, if document was saved, <c>false</c> otherwise.</returns>
        public bool SaveDocument() {
            bool successful = false;

            // Save document to path
            Document.Save (Document.FileUrl, UIDocumentSaveOperation.ForOverwriting, (saveSuccess) => {
                Console.WriteLine ("Save completion: " + saveSuccess);
                if (saveSuccess) {
                    Console.WriteLine ("Document Saved");
                    successful = true;
                } else {
                    Console.WriteLine ("Unable to Save Document");
                    successful=false;
                }
            });

            // Return results
            return successful;
        }
        #endregion

        #region Override Methods
        public override void FinishedLaunching (UIApplication application)
        {

            // Start a new thread to check and see if the user has iCloud
            // enabled.
            new Thread(new ThreadStart(() => {
                // Inform caller that we are checking for iCloud
                CheckingForiCloud = true;

                // Checks to see if the user of this device has iCloud
                // enabled
                var uburl = NSFileManager.DefaultManager.GetUrlForUbiquityContainer(null);

                // Connected to iCloud?
                if (uburl == null)
                {
                    // No, inform caller
                    HasiCloud = false;
                    iCloudUrl =null;
                    Console.WriteLine("Unable to connect to iCloud");
                    InvokeOnMainThread(()=>{
                        var okAlertController = UIAlertController.Create ("iCloud Not Available", "Developer, please check your Entitlements.plist, Bundle ID and Provisioning Profiles.", UIAlertControllerStyle.Alert);
                        okAlertController.AddAction (UIAlertAction.Create ("Ok", UIAlertActionStyle.Default, null));
                        Window.RootViewController.PresentViewController (okAlertController, true, null);
                    });
                }
                else
                {    
                    // Yes, inform caller and save location the Application Container
                    HasiCloud = true;
                    iCloudUrl = uburl;
                    Console.WriteLine("Connected to iCloud");

                    // If we have made the connection with iCloud, start looking for documents
                    InvokeOnMainThread(()=>{
                        // Search for the default document
                        FindDocument ();
                    });
                }

                // Inform caller that we are no longer looking for iCloud
                CheckingForiCloud = false;

            })).Start();

        }

        // This method is invoked when the application is about to move from active to inactive state.
        // OpenGL applications should use this method to pause.
        public override void OnResignActivation (UIApplication application)
        {
        }

        // This method should be used to release shared resources and it should store the application state.
        // If your application supports background execution this method is called instead of WillTerminate
        // when the user quits.
        public override void DidEnterBackground (UIApplication application)
        {
            // Trap all errors
            try {
                // Values to include in the bookmark packet
                var resources = new string[] {
                    NSUrl.FileSecurityKey,
                    NSUrl.ContentModificationDateKey,
                    NSUrl.FileResourceIdentifierKey,
                    NSUrl.FileResourceTypeKey,
                    NSUrl.LocalizedNameKey
                };

                // Create the bookmark
                NSError err;
                Bookmark = Document.FileUrl.CreateBookmarkData (NSUrlBookmarkCreationOptions.WithSecurityScope, resources, iCloudUrl, out err);

                // Was there an error?
                if (err != null) {
                    // Yes, report it
                    Console.WriteLine ("Error Creating Bookmark: {0}", err.LocalizedDescription);
                }
            }
            catch (Exception e) {
                // Report error
                Console.WriteLine ("Error: {0}", e.Message);
            }
        }

        // This method is called as part of the transition from background to active state.
        public override void WillEnterForeground (UIApplication application)
        {
            // Is there any bookmark data?
            if (Bookmark != null) {
                // Trap all errors
                try {
                    // Yes, attempt to restore it
                    bool isBookmarkStale;
                    NSError err;
                    var srcUrl = new NSUrl (Bookmark, NSUrlBookmarkResolutionOptions.WithSecurityScope, iCloudUrl, out isBookmarkStale, out err);

                    // Was there an error?
                    if (err != null) {
                        // Yes, report it
                        Console.WriteLine ("Error Loading Bookmark: {0}", err.LocalizedDescription);
                    } else {
                        // Load document from bookmark
                        OpenDocument (srcUrl);
                    }
                }
                catch (Exception e) {
                    // Report error
                    Console.WriteLine ("Error: {0}", e.Message);
                }
            }

        }

        // This method is called when the application is about to terminate. Save data, if needed.
        public override void WillTerminate (UIApplication application)
        {
        }
        #endregion

        #region Events
        public delegate void DocumentLoadedDelegate(GenericTextDocument document);
        public event DocumentLoadedDelegate DocumentLoaded;

        internal void RaiseDocumentLoaded(GenericTextDocument document) {
            // Inform caller
            if (this.DocumentLoaded != null) {
                this.DocumentLoaded (document);
            }
        }
        #endregion
    }
}

Important

Le code ci-dessus inclut le code de la section Découverte et liste des documents ci-dessus. Il est présenté ici dans son intégralité, tel qu’il apparaît dans une demande réelle. Par souci de simplicité, cet exemple fonctionne avec un seul fichier codé en dur (test.txt) uniquement.

Le code ci-dessus expose plusieurs raccourcis iCloud Drive pour les rendre plus faciles à utiliser dans le reste de l’application.

Ensuite, ajoutez le code suivant à n’importe quel conteneur d’affichage ou de vue qui utilisera le sélecteur de documents ou qui utilisera des documents basés sur le cloud :

using CloudKit;
...

#region Computed Properties
/// <summary>
/// Returns the delegate of the current running application
/// </summary>
/// <value>The this app.</value>
public AppDelegate ThisApp {
    get { return (AppDelegate)UIApplication.SharedApplication.Delegate; }
}
#endregion

Cela ajoute un raccourci pour accéder aux AppDelegate raccourcis iCloud créés ci-dessus et y accéder.

Une fois ce code en place, examinons l’implémentation du contrôleur de vue sélecteur de documents dans une application Xamarin iOS 8.

Utilisation du contrôleur d’affichage du sélecteur de documents

Avant iOS 8, il était très difficile d’accéder aux documents à partir d’une autre application, car il n’existait aucun moyen de découvrir des documents en dehors de l’application à partir de l’application.

Comportement existant

Vue d’ensemble du comportement existant

Examinons l’accès à un document externe avant iOS 8 :

  1. Tout d’abord, l’utilisateur doit ouvrir l’application qui a créé le document à l’origine.
  2. Le document est sélectionné et est UIDocumentInteractionController utilisé pour envoyer le document à la nouvelle application.
  3. Enfin, une copie du document d’origine est placée dans le conteneur de la nouvelle application.

À partir de là, le document est disponible pour l’ouverture et la modification de la deuxième application.

Découverte de documents en dehors du conteneur d’une application

Dans iOS 8, une application peut accéder facilement aux documents en dehors de son propre conteneur d’application :

Découverte de documents en dehors du conteneur d’une application

À l’aide du nouveau sélecteur de documents iCloud ( UIDocumentPickerViewController), une application iOS peut découvrir et accéder directement en dehors de son conteneur d’application. fournit UIDocumentPickerViewController un mécanisme permettant à l’utilisateur d’accorder l’accès à ces documents découverts et de les modifier via des autorisations.

Une application doit choisir d’afficher ses documents dans le sélecteur de documents iCloud et d’être disponible pour que d’autres applications puissent les découvrir et les utiliser. Pour qu’une application Xamarin iOS 8 partage son conteneur d’application, modifiez-la Info.plist dans un éditeur de texte standard et ajoutez les deux lignes suivantes au bas du dictionnaire (entre les <dict>...</dict> balises) :

<key>NSUbiquitousContainerIsDocumentScopePublic</key>
<true/>

fournit UIDocumentPickerViewController une nouvelle interface utilisateur qui permet à l’utilisateur de choisir des documents. Pour afficher le contrôleur d’affichage sélecteur de documents dans une application Xamarin iOS 8, procédez comme suit :

using MobileCoreServices;
...

// Allow the Document picker to select a range of document types
        var allowedUTIs = new string[] {
            UTType.UTF8PlainText,
            UTType.PlainText,
            UTType.RTF,
            UTType.PNG,
            UTType.Text,
            UTType.PDF,
            UTType.Image
        };

        // Display the picker
        //var picker = new UIDocumentPickerViewController (allowedUTIs, UIDocumentPickerMode.Open);
        var pickerMenu = new UIDocumentMenuViewController(allowedUTIs, UIDocumentPickerMode.Open);
        pickerMenu.DidPickDocumentPicker += (sender, args) => {

            // Wireup Document Picker
            args.DocumentPicker.DidPickDocument += (sndr, pArgs) => {

                // IMPORTANT! You must lock the security scope before you can
                // access this file
                var securityEnabled = pArgs.Url.StartAccessingSecurityScopedResource();

                // Open the document
                ThisApp.OpenDocument(pArgs.Url);

                // IMPORTANT! You must release the security lock established
                // above.
                pArgs.Url.StopAccessingSecurityScopedResource();
            };

            // Display the document picker
            PresentViewController(args.DocumentPicker,true,null);
        };

pickerMenu.ModalPresentationStyle = UIModalPresentationStyle.Popover;
PresentViewController(pickerMenu,true,null);
UIPopoverPresentationController presentationPopover = pickerMenu.PopoverPresentationController;
if (presentationPopover!=null) {
    presentationPopover.SourceView = this.View;
    presentationPopover.PermittedArrowDirections = UIPopoverArrowDirection.Down;
    presentationPopover.SourceRect = ((UIButton)s).Frame;
}

Important

Le développeur doit appeler la StartAccessingSecurityScopedResource méthode du avant d’accéder NSUrl à un document externe. La StopAccessingSecurityScopedResource méthode doit être appelée pour libérer le verrou de sécurité dès que le document a été chargé.

Exemple de sortie

Voici un exemple de la façon dont le code ci-dessus affiche un sélecteur de documents lors de l’exécution sur un appareil iPhone :

  1. L’utilisateur démarre l’application et l’interface main s’affiche :

    L’interface main s’affiche

  2. L’utilisateur appuie sur le bouton Action en haut de l’écran et est invité à sélectionner un fournisseur de documents dans la liste des fournisseurs disponibles :

    Sélectionnez un fournisseur de documents dans la liste des fournisseurs disponibles

  3. Le contrôleur d’affichage du sélecteur de documents s’affiche pour le fournisseur de documents sélectionné :

    Le contrôleur d’affichage du sélecteur de documents s’affiche

  4. L’utilisateur appuie sur un dossier de document pour afficher son contenu :

    Contenu du dossier de document

  5. L’utilisateur sélectionne un document et le sélecteur de documents est fermé.

  6. L’interface main est réaffichée, le document est chargé à partir du conteneur externe et son contenu s’affiche.

L’affichage réel du contrôleur d’affichage du sélecteur de documents dépend des fournisseurs de documents que l’utilisateur a installés sur l’appareil et du mode sélecteur de documents qui a été implémenté. L’exemple ci-dessus utilise le mode Open. Les autres types de mode seront décrits en détail ci-dessous.

Gestion des documents externes

Comme indiqué ci-dessus, avant iOS 8, une application ne pouvait accéder qu’aux documents qui faisaient partie de son conteneur d’application. Dans iOS 8, une application peut accéder aux documents à partir de sources externes :

Vue d’ensemble de la gestion des documents externes

Lorsque l’utilisateur sélectionne un document à partir d’une source externe, un document de référence est écrit dans le conteneur d’application qui pointe vers le document d’origine.

Pour faciliter l’ajout de cette nouvelle fonctionnalité aux applications existantes, plusieurs nouvelles fonctionnalités ont été ajoutées à l’API NSMetadataQuery . En règle générale, une application utilise l’étendue de document omniprésente pour répertorier les documents qui se trouvent dans son conteneur d’application. À l’aide de cette étendue, seuls les documents du conteneur d’application continueront d’être affichés.

L’utilisation de la nouvelle étendue de document externe omniprésente retourne les documents qui vivent en dehors du conteneur d’application et retourne les métadonnées pour eux. NSMetadataItemUrlKey pointe vers l’URL où se trouve réellement le document.

Parfois, une application ne souhaite pas utiliser les documents vers lesquels la référence est pointée. Au lieu de cela, l’application souhaite utiliser directement le document de référence. Par exemple, l’application peut souhaiter afficher le document dans le dossier de l’application dans l’interface utilisateur, ou pour permettre à l’utilisateur de déplacer les références à l’intérieur d’un dossier.

Dans iOS 8, un nouveau NSMetadataItemUrlInLocalContainerKey a été fourni pour accéder directement au document de référence. Cette clé pointe vers la référence réelle au document externe dans un conteneur d’application.

NSMetadataUbiquitousItemIsExternalDocumentKey est utilisé pour tester si un document est externe au conteneur d’une application. NSMetadataUbiquitousItemContainerDisplayNameKey est utilisé pour accéder au nom du conteneur qui héberge la copie d’origine d’un document externe.

Pourquoi les références de document sont requises

La main raison pour laquelle iOS 8 utilise des références pour accéder à des documents externes est la sécurité. Aucune application n’a accès au conteneur d’une autre application. Seul le sélecteur de documents peut le faire, car il est hors processus et dispose d’un accès à l’échelle du système.

La seule façon d’accéder à un document en dehors du conteneur d’application consiste à utiliser le sélecteur de documents et si l’URL retournée par le sélecteur est définie sur l’étendue de la sécurité. L’URL étendue à la sécurité contient juste assez d’informations pour sélectionner le document, ainsi que les droits délimités requis pour accorder à une application l’accès au document.

Il est important de noter que si l’URL étendue à la sécurité a été sérialisée dans une chaîne, puis dés sérialisée, les informations de sécurité sont perdues et le fichier est inaccessible à partir de l’URL. La fonctionnalité Référence de document fournit un mécanisme pour revenir aux fichiers pointés par ces URL.

Par conséquent, si l’application acquiert un NSUrl à partir de l’un des documents de référence, elle a déjà l’étendue de sécurité attachée et peut être utilisée pour accéder au fichier. Pour cette raison, il est fortement suggéré au développeur d’utiliser UIDocument , car il gère toutes ces informations et traite pour eux.

Utilisation de signets

Il n’est pas toujours possible d’énumérer les documents d’une application pour revenir à un document spécifique, par exemple lors de la restauration d’état. iOS 8 fournit un mécanisme permettant de créer des signets qui ciblent directement un document donné.

Le code suivant crée un signet à partir d’une propriété d’un UIDocumentFileUrl :

// Trap all errors
try {
    // Values to include in the bookmark packet
    var resources = new string[] {
        NSUrl.FileSecurityKey,
        NSUrl.ContentModificationDateKey,
        NSUrl.FileResourceIdentifierKey,
        NSUrl.FileResourceTypeKey,
        NSUrl.LocalizedNameKey
    };

    // Create the bookmark
    NSError err;
    Bookmark = Document.FileUrl.CreateBookmarkData (NSUrlBookmarkCreationOptions.WithSecurityScope, resources, iCloudUrl, out err);

    // Was there an error?
    if (err != null) {
        // Yes, report it
        Console.WriteLine ("Error Creating Bookmark: {0}", err.LocalizedDescription);
    }
}
catch (Exception e) {
    // Report error
    Console.WriteLine ("Error: {0}", e.Message);
}

L’API Bookmark existante est utilisée pour créer un signet sur un existant NSUrl qui peut être enregistré et chargé pour fournir un accès direct à un fichier externe. Le code suivant restaure un signet créé ci-dessus :

if (Bookmark != null) {
    // Trap all errors
    try {
        // Yes, attempt to restore it
        bool isBookmarkStale;
        NSError err;
        var srcUrl = new NSUrl (Bookmark, NSUrlBookmarkResolutionOptions.WithSecurityScope, iCloudUrl, out isBookmarkStale, out err);

        // Was there an error?
        if (err != null) {
            // Yes, report it
            Console.WriteLine ("Error Loading Bookmark: {0}", err.LocalizedDescription);
        } else {
            // Load document from bookmark
            OpenDocument (srcUrl);
        }
    }
    catch (Exception e) {
        // Report error
        Console.WriteLine ("Error: {0}", e.Message);
    }
}

Ouvrir le mode d’importation et le sélecteur de documents

Le contrôleur d’affichage du sélecteur de documents propose deux modes de fonctionnement différents :

  1. Mode Ouvrir : dans ce mode, lorsque l’utilisateur sélectionne et document externe, le sélecteur de documents crée un signet avec étendue de sécurité dans le conteneur d’application.

    Un signet délimité à la sécurité dans le conteneur d’application

  2. Mode d’importation : dans ce mode, lorsque l’utilisateur sélectionne et document externe, le sélecteur de documents ne crée pas de signet, mais copie le fichier dans un emplacement temporaire et fournit à l’application l’accès au document à cet emplacement :

    Le sélecteur de documents copie le fichier dans un emplacement temporaire et fournit à l’application l’accès au document à cet emplacement
    Une fois l’application terminée pour une raison quelconque, l’emplacement temporaire est vidé et le fichier supprimé. Si l’application doit conserver l’accès au fichier, elle doit effectuer une copie et le placer dans son conteneur d’application.

Le mode Ouvrir est utile lorsque l’application souhaite collaborer avec une autre application et partager les modifications apportées au document avec cette application. Le mode d’importation est utilisé lorsque l’application ne souhaite pas partager ses modifications dans un document avec d’autres applications.

Rendre un document externe

Comme indiqué ci-dessus, une application iOS 8 n’a pas accès aux conteneurs en dehors de son propre conteneur d’application. L’application peut écrire dans son propre conteneur localement ou dans un emplacement temporaire, puis utiliser un mode de document spécial pour déplacer le document résultant en dehors du conteneur d’application vers un emplacement choisi par l’utilisateur.

Pour déplacer un document vers un emplacement externe, procédez comme suit :

  1. Commencez par créer un document dans un emplacement local ou temporaire.
  2. Créez un NSUrl qui pointe vers le nouveau document.
  3. Ouvrez un nouveau contrôleur d’affichage du sélecteur de documents et passez-lui le NSUrl avec le mode de MoveToService .
  4. Une fois que l’utilisateur a choisi un nouvel emplacement, le document est déplacé de son emplacement actuel vers le nouvel emplacement.
  5. Un document de référence sera écrit dans le conteneur d’application de l’application afin que le fichier soit toujours accessible par l’application qui crée.

Le code suivant peut être utilisé pour déplacer un document vers un emplacement externe : var picker = new UIDocumentPickerViewController (srcURL, UIDocumentPickerMode.MoveToService);

Le document de référence retourné par le processus ci-dessus est exactement le même que celui créé par le mode d’ouverture du sélecteur de documents. Toutefois, il arrive que l’application souhaite déplacer un document sans conserver de référence à celui-ci.

Pour déplacer un document sans générer de référence, utilisez le ExportToService mode . Exemple : var picker = new UIDocumentPickerViewController (srcURL, UIDocumentPickerMode.ExportToService);

Lors de l’utilisation du ExportToService mode , le document est copié dans le conteneur externe et la copie existante est conservée à son emplacement d’origine.

Extensions du fournisseur de documents

Avec iOS 8, Apple souhaite que l’utilisateur final puisse accéder à l’un de ses documents basés sur le cloud, où qu’il se trouve réellement. Pour atteindre cet objectif, iOS 8 fournit un nouveau mécanisme d’extension du fournisseur de documents.

Qu’est-ce qu’une extension de fournisseur de documents ?

En termes simples, une extension de fournisseur de documents est un moyen pour un développeur ou un tiers de fournir à une application un autre stockage de documents accessible exactement de la même façon que l’emplacement de stockage iCloud existant.

L’utilisateur peut sélectionner l’un de ces emplacements de stockage alternatifs dans le sélecteur de documents et utiliser exactement les mêmes modes d’accès (Ouvrir, Importer, Déplacer ou Exporter) pour travailler avec des fichiers à cet emplacement.

Cette opération est implémentée à l’aide de deux extensions différentes :

  • Extension du sélecteur de documents : fournit une UIViewController sous-classe qui fournit une interface graphique permettant à l’utilisateur de choisir un document à partir d’un autre emplacement de stockage. Cette sous-classe s’affiche dans le cadre du contrôleur d’affichage du sélecteur de documents.
  • Extension file provide : il s’agit d’une extension non-interface utilisateur qui traite de la fourniture du contenu des fichiers. Ces extensions sont fournies par le biais de La coordination des fichiers ( NSFileCoordinator ). Il s’agit d’un autre cas important où la coordination des fichiers est requise.

Le diagramme suivant montre le flux de données classique lors de l’utilisation des extensions de fournisseur de documents :

Ce diagramme montre le flux de données classique lors de l’utilisation d’extensions de fournisseur de documents

Le processus suivant se produit :

  1. L’application présente un contrôleur de sélecteur de documents pour permettre à l’utilisateur de sélectionner un fichier à utiliser.
  2. L’utilisateur sélectionne un autre emplacement de fichier et l’extension personnalisée UIViewController est appelée pour afficher l’interface utilisateur.
  3. L’utilisateur sélectionne un fichier à partir de cet emplacement et l’URL est renvoyée au sélecteur de documents.
  4. Le sélecteur de documents sélectionne l’URL du fichier et le retourne à l’application sur laquelle l’utilisateur peut travailler.
  5. L’URL est passée au coordinateur de fichiers pour retourner le contenu des fichiers à l’application.
  6. Le coordinateur de fichiers appelle l’extension de fournisseur de fichiers personnalisée pour récupérer le fichier.
  7. Le contenu du fichier est retourné au coordinateur de fichiers.
  8. Le contenu du fichier est retourné à l’application.

Sécurité et signets

Cette section examine rapidement le fonctionnement de la sécurité et de l’accès aux fichiers persistants via les signets avec les extensions de fournisseur de documents. Contrairement au fournisseur de documents iCloud, qui enregistre automatiquement la sécurité et les signets dans le conteneur d’applications, les extensions de fournisseur de documents ne font pas partie du système de référence de document.

Par exemple : dans un paramètre Entreprise qui fournit son propre magasin de données sécurisé à l’échelle de l’entreprise, les administrateurs ne veulent pas que les informations d’entreprise confidentielles soient consultées ou traitées par les serveurs iCloud publics. Par conséquent, le système de référence de document intégré ne peut pas être utilisé.

Le système de signets peut toujours être utilisé et il incombe à l’extension de fournisseur de fichiers de traiter correctement une URL avec signet et de retourner le contenu du document vers lequel elle pointe.

Pour des raisons de sécurité, iOS 8 a une couche d’isolation qui conserve les informations sur l’application qui a accès à quel identificateur à l’intérieur de quel fournisseur de fichiers. Il est à noter que tous les accès aux fichiers sont contrôlés par cette couche d’isolation.

Le diagramme suivant montre le flux de données lors de l’utilisation de signets et d’une extension de fournisseur de documents :

Ce diagramme montre le flux de données lors de l’utilisation de signets et d’une extension de fournisseur de documents

Le processus suivant se produit :

  1. L’application est sur le point d’entrer en arrière-plan et doit conserver son état. Il appelle NSUrl pour créer un signet dans un fichier dans un autre stockage.
  2. NSUrl appelle l’extension de fournisseur de fichiers pour obtenir une URL persistante vers le document.
  3. L’extension du fournisseur de fichiers retourne l’URL sous la forme d’une chaîne à .NSUrl
  4. Le NSUrl regroupe l’URL dans un signet et la retourne à l’application.
  5. Lorsque l’application se réveille d’être en arrière-plan et doit restaurer l’état, elle transmet le signet à NSUrl .
  6. NSUrl appelle l’extension de fournisseur de fichiers avec l’URL du fichier.
  7. Le fournisseur d’extension de fichier accède au fichier et retourne l’emplacement du fichier à NSUrl .
  8. L’emplacement du fichier est fourni avec des informations de sécurité et retourné à l’application.

À partir de là, l’application peut accéder au fichier et l’utiliser normalement.

Écriture de fichiers

Cette section examine rapidement le fonctionnement de l’écriture de fichiers dans un autre emplacement avec une extension de fournisseur de documents. L’application iOS utilise La coordination des fichiers pour enregistrer des informations sur le disque à l’intérieur du conteneur d’application. Peu de temps après l’écriture du fichier, l’extension du fournisseur de fichiers est avertie de la modification.

À ce stade, l’extension du fournisseur de fichiers peut commencer à charger le fichier à l’autre emplacement (ou marquer le fichier comme sale et nécessitant un chargement).

Création d’extensions de fournisseur de documents

La création d’extensions de fournisseur de documents n’entre pas dans le cadre de cet article d’introduction. Ces informations sont fournies ici pour montrer que, en fonction des extensions qu’un utilisateur a chargées sur son appareil iOS, une application peut avoir accès aux emplacements de stockage de documents en dehors de l’emplacement iCloud fourni par Apple.

Le développeur doit être conscient de ce fait lors de l’utilisation du sélecteur de documents et de l’utilisation de documents externes. Ils ne doivent pas supposer que ces documents sont hébergés dans iCloud.

Pour plus d’informations sur la création d’un fournisseur de stockage ou d’une extension de sélecteur de documents, consultez le document Présentation des extensions d’application .

Migration vers iCloud Drive

Sur iOS 8, les utilisateurs peuvent choisir de continuer à utiliser le système de documents iCloud existant utilisé dans iOS 7 (et les systèmes antérieurs) ou ils peuvent choisir de migrer des documents existants vers le nouveau mécanisme iCloud Drive.

Sur Mac OS X Yosemite, Apple ne fournit pas la compatibilité descendante, de sorte que tous les documents doivent être migrés vers iCloud Drive ou ils ne seront plus mis à jour entre les appareils.

Une fois le compte d’utilisateur migré vers iCloud Drive, seuls les appareils utilisant iCloud Drive pourront propager les modifications à Documents sur ces appareils.

Important

Les développeurs doivent savoir que les nouvelles fonctionnalités décrites dans cet article ne sont disponibles que si le compte de l’utilisateur a été migré vers iCloud Drive.

Résumé

Cet article a abordé les modifications apportées aux API iCloud existantes requises pour prendre en charge iCloud Drive et le nouveau contrôleur d’affichage du sélecteur de documents. Il a abordé la coordination des fichiers et la raison pour laquelle elle est importante lors de l’utilisation de documents basés sur le cloud. Il a abordé la configuration requise pour activer des documents basés sur le cloud dans une application Xamarin.iOS et a donné un aperçu d’introduction à l’utilisation de documents en dehors du conteneur d’application d’une application à l’aide du contrôleur d’affichage du sélecteur de documents.

En outre, cet article a brièvement abordé les extensions du fournisseur de documents et la raison pour laquelle le développeur doit les connaître lors de l’écriture d’applications capables de gérer des documents basés sur le cloud.