Selezione documenti in Xamarin.iOS

Selezione documenti consente di condividere documenti tra le app. Questi documenti possono essere archiviati in iCloud o in una directory diversa dell'app. I documenti vengono condivisi tramite il set di estensioni del provider di documenti che l'utente ha installato nel dispositivo.

A causa della difficoltà di mantenere i documenti sincronizzati tra app e cloud, introducono una certa complessità necessaria.

Requisiti

Per completare i passaggi presentati in questo articolo, è necessario quanto segue:

  • Xcode 7 e iOS 8 o versione successiva : le API Xcode 7 e iOS 8 o successive di Apple devono essere installate e configurate nel computer dello sviluppatore.
  • Visual Studio o Visual Studio per Mac: deve essere installata la versione più recente di Visual Studio per Mac.
  • Dispositivo iOS: un dispositivo iOS che esegue iOS 8 o versione successiva.

Modifiche a iCloud

Per implementare le nuove funzionalità di Selezione documenti, sono state apportate le modifiche seguenti al servizio iCloud di Apple:

  • Il daemon iCloud è stato completamente riscritto usando CloudKit.
  • Le funzionalità di iCloud esistenti sono state rinominate iCloud Drive.
  • Il supporto per il sistema operativo Microsoft Windows è stato aggiunto a iCloud.
  • Una cartella iCloud è stata aggiunta nel Finder di Mac OS.
  • I dispositivi iOS possono accedere al contenuto della cartella iCloud di Mac OS.

Importante

Apple fornisce strumenti per aiutare gli sviluppatori a gestire correttamente il Regolamento generale sulla protezione dei dati (GDPR) dell'Unione Europea.

Che cos'è un documento?

Quando si fa riferimento a un documento in iCloud, si tratta di una singola entità autonoma e deve essere percepita come tale dall'utente. Un utente può voler modificare il documento o condividerlo con altri utenti ,ad esempio tramite posta elettronica.

Esistono diversi tipi di file che l'utente riconoscerà immediatamente come Documenti, ad esempio Pagine, Keynote o Numeri. Tuttavia, iCloud non è limitato a questo concetto. Ad esempio, lo stato di un gioco (ad esempio una partita di scacchi) può essere considerato come un documento e archiviato in iCloud. Questo file può essere passato tra i dispositivi di un utente e consentire loro di prelevare un gioco in cui è stato interrotto su un dispositivo diverso.

Gestione dei documenti

Prima di approfondire il codice necessario per usare selezione documenti con Xamarin, questo articolo illustra le procedure consigliate per l'uso di documenti iCloud e diverse delle modifiche apportate alle API esistenti necessarie per supportare la selezione documenti.

Uso del coordinamento dei file

Poiché un file può essere modificato da diverse posizioni, è necessario usare il coordinamento per evitare la perdita di dati.

Uso del coordinamento dei file

Si esaminerà ora l'illustrazione precedente:

  1. Un dispositivo iOS che usa il coordinamento dei file crea un nuovo documento e lo salva nella cartella iCloud.
  2. iCloud salva il file modificato nel cloud per la distribuzione in ogni dispositivo.
  3. Un Mac collegato vede il file modificato nella cartella iCloud e usa Coordinamento file per copiare le modifiche apportate al file.
  4. Un dispositivo che non usa Coordinamento file apporta una modifica al file e lo salva nella cartella iCloud. Queste modifiche vengono replicate immediatamente negli altri dispositivi.

Si supponga che il dispositivo iOS originale o il Mac stia modificando il file, ora le modifiche andranno perse e sovrascritte con la versione del file dal dispositivo non coordinato. Per evitare la perdita di dati, il coordinamento dei file è un must quando si lavora con documenti basati sul cloud.

Uso di UIDocument

UIDocument rende le cose semplici (o NSDocument in macOS) eseguendo tutto il lavoro pesante per lo sviluppatore. Fornisce un coordinamento di file integrato con code in background per evitare di bloccare l'interfaccia utente dell'applicazione.

UIDocument espone più API di alto livello che semplificano lo sviluppo di un'applicazione Xamarin per qualsiasi scopo richiesto dallo sviluppatore.

Il codice seguente crea una sottoclasse di UIDocument per implementare un documento generico basato su testo che può essere usato per archiviare e recuperare testo da 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 presentata in precedenza verrà usata in questo articolo quando si usano selezione documenti ed esterni in un'applicazione Xamarin.iOS 8.

Coordinamento dei file asincrono

iOS 8 offre diverse nuove funzionalità di coordinamento dei file asincroni tramite le nuove API di coordinamento dei file. Prima di iOS 8, tutte le API di coordinamento dei file esistenti erano totalmente sincrone. Ciò significa che lo sviluppatore è stato responsabile dell'implementazione del proprio accodamento in background per impedire a Coordinamento file di bloccare l'interfaccia utente dell'applicazione.

La nuova NSFileAccessIntent classe contiene un URL che punta al file e diverse opzioni per controllare il tipo di coordinamento necessario. Il codice seguente illustra lo spostamento di un file da un percorso a un altro usando finalità:

// 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);
    }
});

Individuazione ed elenco di documenti

Il modo per individuare ed elencare i documenti consiste nell'usare le API esistenti NSMetadataQuery . Questa sezione illustra le nuove funzionalità aggiunte a che semplificano l'uso dei documenti rispetto a NSMetadataQuery prima.

Comportamento esistente

Prima di iOS 8, NSMetadataQuery era lento a recuperare le modifiche dei file locali, ad esempio: eliminazioni, crea e rinomina.

Panoramica delle modifiche ai file locali NSMetadataQuery

Nel diagramma precedente:

  1. Per i file già esistenti nel contenitore dell'applicazione, NSMetadataQuery i record esistenti NSMetadata sono già stati creati e raggruppati in modo che siano immediatamente disponibili per l'applicazione.
  2. L'applicazione crea un nuovo file nel contenitore dell'applicazione.
  3. Si verifica un ritardo prima di NSMetadataQuery visualizzare la modifica al contenitore dell'applicazione e creare il record richiesto NSMetadata .

A causa del ritardo nella creazione del NSMetadata record, l'applicazione doveva avere due origini dati aperte: una per le modifiche ai file locali e una per le modifiche basate sul cloud.

Cuciture

In iOS 8 NSMetadataQuery è più facile da usare direttamente con una nuova funzionalità denominata Stitching:

NSMetadataQuery con una nuova funzionalità denominata Stitching

Uso del punto nel diagramma precedente:

  1. Come in precedenza, per i file che esistono già nel contenitore dell'applicazione, NSMetadataQuery i record esistenti sono già NSMetadata stati creati e inseriti nello spooling.
  2. L'applicazione crea un nuovo file nel contenitore dell'applicazione usando il coordinamento dei file.
  3. Un hook nel contenitore dell'applicazione vede la modifica e le chiamate NSMetadataQuery per creare il record necessario NSMetadata .
  4. Il NSMetadata record viene creato direttamente dopo il file e reso disponibile per l'applicazione.

L'uso di Stitching per l'applicazione non deve più aprire un'origine dati per monitorare le modifiche dei file locali e basate sul cloud. Ora l'applicazione può basarsi direttamente su NSMetadataQuery .

Importante

Il punto funziona solo se l'applicazione usa coordinamento file come illustrato nella sezione precedente. Se il coordinamento dei file non viene usato, per impostazione predefinita le API sono il comportamento esistente di iOS 8.

Nuove funzionalità di metadati iOS 8

In iOS 8 sono state aggiunte NSMetadataQuery le nuove funzionalità seguenti:

  • NSMetatadataQuery ora può elencare documenti non locali archiviati nel cloud.
  • Sono state aggiunte nuove API per accedere alle informazioni sui metadati nei documenti basati sul cloud.
  • È disponibile una nuova NSUrl_PromisedItems API che accederà agli attributi di file che potrebbero o meno avere il contenuto disponibile in locale.
  • Utilizzare il GetPromisedItemResourceValue metodo per ottenere informazioni su un determinato file o usare il GetPromisedItemResourceValues metodo per ottenere informazioni su più file alla volta.

Sono stati aggiunti due nuovi flag di coordinamento dei file per la gestione dei metadati:

  • NSFileCoordinatorReadImmediatelyAvailableMetadataOnly
  • NSFileCoordinatorWriteContentIndependentMetadataOnly

Con i flag precedenti, non è necessario che il contenuto del file di documento sia disponibile in locale per poterli usare.

Il segmento di codice seguente illustra come usare NSMetadataQuery per eseguire una query per l'esistenza di un file specifico e compilare il file, se non esiste:

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

Anteprime documento

Apple ritiene che l'esperienza utente migliore quando si elencano documenti per un'applicazione consiste nell'usare le anteprime. In questo modo si ottiene il contesto degli utenti finali, in modo da poter identificare rapidamente il documento da usare.

Prima di iOS 8, la visualizzazione delle anteprime dei documenti richiedeva un'implementazione personalizzata. Le novità di iOS 8 sono attributi del file system che consentono allo sviluppatore di lavorare rapidamente con le anteprime dei documenti.

Recupero delle anteprime dei documenti

Chiamando i GetPromisedItemResourceValue metodi o GetPromisedItemResourceValues , NSUrl_PromisedItems API, viene restituito un NSUrlThumbnailDictionaryoggetto . L'unica chiave attualmente presente in questo dizionario è NSThumbnial1024X1024SizeKey e corrisponde a UIImage.

Salvataggio delle anteprime dei documenti

Il modo più semplice per salvare un'anteprima consiste nell'usare UIDocument. Chiamando il GetFileAttributesToWrite metodo di UIDocument e impostando l'anteprima, verrà salvato automaticamente quando il file di documento è. Il Daemon iCloud vedrà questa modifica e la propaga in iCloud. In Mac OS X le anteprime vengono generate automaticamente per lo sviluppatore dal plug-in Quick Look.

Con le nozioni di base sull'uso dei documenti basati su iCloud, insieme alle modifiche apportate all'API esistente, è possibile implementare il controller di visualizzazione selezione documenti in un'applicazione per dispositivi mobili Xamarin iOS 8.

Abilitazione di iCloud in Xamarin

Prima di poter usare Selezione documenti in un'applicazione Xamarin.iOS, il supporto di iCloud deve essere abilitato sia nell'applicazione che tramite Apple.

La procedura seguente illustra il processo di provisioning per iCloud.

  1. Creare un contenitore iCloud.
  2. Creare un ID app contenente l'servizio app iCloud.
  3. Creare un profilo di provisioning che includa questo ID app.

La guida Uso delle funzionalità illustra i primi due passaggi. Per creare un profilo di provisioning, seguire la procedura descritta nella Guida al profilo di provisioning.

La procedura seguente illustra il processo di configurazione dell'applicazione per iCloud:

Effettua le operazioni seguenti:

  1. Aprire il progetto in Visual Studio per Mac o Visual Studio.

  2. Nella Esplora soluzioni fare clic con il pulsante destro del mouse sul progetto e scegliere Opzioni.

  3. Nella finestra di dialogo Opzioni selezionare Applicazione iOS, assicurarsi che l'identificatore bundle corrisponda a quello definito in ID app creato in precedenza per l'applicazione.

  4. Selezionare Firma bundle iOS, selezionare l'identità dello sviluppatore e il profilo di provisioning creato in precedenza.

  5. Fare clic sul pulsante OK per salvare le modifiche e chiudere la finestra di dialogo.

  6. Fare clic con Entitlements.plist il pulsante destro del mouse sul Esplora soluzioni per aprirlo nell'editor.

    Importante

    In Visual Studio potrebbe essere necessario aprire l'editor Entitlement facendo clic con il pulsante destro del mouse su di esso, selezionando Apri con e selezionando Editor elenco proprietà

  7. Selezionare Abilita iCloud , iCloud Documents , Key-value storage e CloudKit .

  8. Verificare che il contenitore esista per l'applicazione (come creato in precedenza). Esempio: iCloud.com.your-company.AppName

  9. Salvare le modifiche apportate al file.

Per altre informazioni sui diritti, vedere la guida Uso dei diritti .

Con la configurazione precedente, l'applicazione può ora usare documenti basati sul cloud e il nuovo controller di visualizzazione selezione documenti.

Codice di installazione comune

Prima di iniziare a usare il controller di visualizzazione selezione documenti, è necessario un codice di installazione standard. Per iniziare, modificare il file dell'applicazione AppDelegate.cs e renderlo simile al seguente:

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

Importante

Il codice precedente include il codice della sezione Individuazione ed elenco di documenti precedente. Viene presentato qui nella sua interezza, come appare in un'applicazione effettiva. Per semplicità, questo esempio funziona solo con un singolo file hardcoded (test.txt).

Il codice precedente espone diversi collegamenti a iCloud Drive per semplificarne l'uso nel resto dell'applicazione.

Aggiungere quindi il codice seguente a qualsiasi visualizzazione o contenitore di visualizzazione che verrà usato selezione documenti o uso di documenti basati sul 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

In questo modo viene aggiunto un collegamento per accedere ai AppDelegate collegamenti iCloud creati in precedenza.

Con questo codice, si esaminerà ora l'implementazione del controller di visualizzazione selezione documenti in un'applicazione Xamarin iOS 8.

Uso del controller di visualizzazione selezione documenti

Prima di iOS 8, era molto difficile accedere a Documenti da un'altra applicazione perché non c'era modo di individuare documenti all'esterno dell'applicazione dall'interno dell'app.

Comportamento esistente

Panoramica del comportamento esistente

Esaminiamo ora l'accesso a un documento esterno prima di iOS 8:

  1. In primo luogo, l'utente dovrà aprire l'applicazione che ha originariamente creato il documento.
  2. Il documento è selezionato e viene UIDocumentInteractionController utilizzato per inviare il documento alla nuova applicazione.
  3. Infine, una copia del documento originale viene inserita nel contenitore della nuova applicazione.

Da qui il documento è disponibile per la seconda applicazione per aprire e modificare.

Individuazione di documenti all'esterno del contenitore di un'app

In iOS 8 un'applicazione è in grado di accedere ai documenti all'esterno del proprio contenitore di applicazioni con facilità:

Individuazione di documenti all'esterno del contenitore di un'app

Usando la nuova selezione documenti iCloud ( UIDocumentPickerViewController), un'applicazione iOS può individuare e accedere direttamente all'esterno del contenitore dell'applicazione. Fornisce UIDocumentPickerViewController un meccanismo per consentire all'utente di concedere l'accesso e modificare i documenti individuati tramite autorizzazioni.

Un'applicazione deve acconsentire esplicitamente affinché i documenti vengano visualizzati in Selezione documenti iCloud e siano disponibili per consentire ad altre applicazioni di individuarli e usarli. Per avere un'applicazione Xamarin iOS 8 condividere il contenitore dell'applicazione, modificarlo Info.plist in un editor di testo standard e aggiungere le due righe seguenti alla fine del dizionario (tra i <dict>...</dict> tag):

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

Offre UIDocumentPickerViewController una nuova interfaccia utente ideale che consente all'utente di scegliere documenti. Per visualizzare il controller di visualizzazione selezione documenti in un'applicazione Xamarin iOS 8, eseguire le operazioni seguenti:

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;
}

Importante

Lo sviluppatore deve chiamare il StartAccessingSecurityScopedResource metodo di prima che NSUrl sia possibile accedere a un documento esterno. Il StopAccessingSecurityScopedResource metodo deve essere chiamato per rilasciare il blocco di sicurezza non appena il documento è stato caricato.

Output di esempio

Di seguito è riportato un esempio di come il codice precedente visualizzerebbe una selezione documenti quando viene eseguita in un dispositivo i Telefono:

  1. L'utente avvia l'applicazione e viene visualizzata l'interfaccia principale:

    Viene visualizzata l'interfaccia principale

  2. L'utente tocca il pulsante Azione nella parte superiore della schermata e viene chiesto di selezionare un provider di documenti dall'elenco dei provider disponibili:

    Selezionare un provider di documenti dall'elenco dei provider disponibili

  3. Il controller di visualizzazione selezione documenti viene visualizzato per il provider di documenti selezionato:

    Viene visualizzato il controller di visualizzazione selezione documenti

  4. L'utente tocca una cartella documento per visualizzarne il contenuto:

    Contenuto della cartella documento

  5. L'utente seleziona un documento e la selezione documenti è chiusa.

  6. L'interfaccia principale viene riprodotta, il documento viene caricato dal contenitore esterno e dal relativo contenuto visualizzato.

La visualizzazione effettiva del controller di visualizzazione selezione documenti dipende dai provider di documenti installati dall'utente nel dispositivo e dalla modalità selezione documenti implementata. L'esempio precedente usa la modalità Aperta, gli altri tipi di modalità verranno descritti in dettaglio di seguito.

Gestione di documenti esterni

Come illustrato in precedenza, prima di iOS 8, un'applicazione poteva accedere solo ai documenti che facevano parte del contenitore dell'applicazione. In iOS 8 un'applicazione può accedere a Documenti da origini esterne:

Panoramica sulla gestione di documenti esterni

Quando l'utente seleziona un documento da un'origine esterna, un documento di riferimento viene scritto nel contenitore dell'applicazione che punta al documento originale.

Per facilitare l'aggiunta di questa nuova funzionalità nelle applicazioni esistenti, all'API NSMetadataQuery sono state aggiunte diverse nuove funzionalità. In genere, un'applicazione usa l'ambito documento ubiquitous per elencare i documenti che risiedono all'interno del contenitore dell'applicazione. Usando questo ambito, verranno visualizzati solo i documenti all'interno del contenitore dell'applicazione.

L'uso del nuovo ambito documento esterno Ubiquitous restituirà i documenti che risiedono all'esterno del contenitore dell'applicazione e restituiranno i metadati per tali documenti. Punta NSMetadataItemUrlKey all'URL in cui si trova effettivamente il documento.

In alcuni casi un'applicazione non vuole usare i documenti a cui punta il riferimento. L'app vuole invece usare direttamente il documento di riferimento. Ad esempio, l'app potrebbe voler visualizzare il documento nella cartella dell'applicazione nell'interfaccia utente o consentire all'utente di spostare i riferimenti all'interno di una cartella.

In iOS 8 è stato fornito un nuovo NSMetadataItemUrlInLocalContainerKey oggetto per accedere direttamente al documento di riferimento. Questa chiave punta al riferimento effettivo al documento esterno in un contenitore di applicazioni.

Viene NSMetadataUbiquitousItemIsExternalDocumentKey usato per verificare se un documento è esterno al contenitore di un'applicazione. Viene NSMetadataUbiquitousItemContainerDisplayNameKey utilizzato per accedere al nome del contenitore che ospita la copia originale di un documento esterno.

Perché i riferimenti ai documenti sono obbligatori

Il motivo principale per cui iOS 8 usa riferimenti per accedere a documenti esterni è la sicurezza. Nessuna applicazione ha accesso al contenitore di un'altra applicazione. Questa operazione può essere eseguita solo dal selettore documenti, perché è in esaurimento e ha accesso a livello di sistema.

L'unico modo per accedere a un documento all'esterno del contenitore di applicazioni consiste nell'usare selezione documenti e se l'URL restituito dalla selezione è Ambito di sicurezza. L'URL con ambito di sicurezza contiene informazioni sufficienti per selezionare il documento insieme ai diritti con ambito necessari per concedere a un'applicazione l'accesso al documento.

È importante notare che se l'URL con ambito di sicurezza è stato serializzato in una stringa e quindi de serializzato, le informazioni di sicurezza andrebbero perse e il file non sarebbe accessibile dall'URL. La funzionalità Riferimento documento fornisce un meccanismo per tornare ai file a cui puntano questi URL.

Pertanto, se l'applicazione acquisisce un oggetto NSUrl da uno dei documenti di riferimento, ha già l'ambito di sicurezza associato e può essere usato per accedere al file. Per questo motivo, è consigliabile che lo sviluppatore usi UIDocument perché gestisce tutte queste informazioni e processi per loro.

Uso dei segnalibri

Non è sempre possibile enumerare i documenti di un'applicazione per tornare a un documento specifico, ad esempio quando si esegue il ripristino dello stato. iOS 8 fornisce un meccanismo per creare segnalibri destinati direttamente a un determinato documento.

Il codice seguente creerà un segnalibro dalla proprietà di FileUrl un UIDocumentoggetto :

// 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 Segnalibro esistente viene usata per creare un segnalibro su un oggetto esistente NSUrl che può essere salvato e caricato per fornire l'accesso diretto a un file esterno. Il codice seguente ripristina un segnalibro creato in precedenza:

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);
    }
}

Aprire e importare la modalità e la selezione documenti

Il controller di visualizzazione selezione documenti offre due diverse modalità di funzionamento:

  1. Modalità aperta: in questa modalità, quando l'utente seleziona e esterno Document, selezione documenti creerà un segnalibro con ambito di sicurezza nel contenitore dell'applicazione.

    Segnalibro con ambito di sicurezza nel contenitore dell'applicazione

  2. Modalità di importazione: in questa modalità, quando l'utente seleziona e esterno Document, selezione documenti non crea un segnalibro, ma copia il file in un percorso temporaneo e fornisce all'applicazione l'accesso al documento in questo percorso:

    Selezione documenti copierà il file in un percorso temporaneo e fornirà all'applicazione l'accesso al documento in questo percorso
    Una volta terminata l'applicazione per qualsiasi motivo, il percorso temporaneo viene svuotato e il file rimosso. Se l'applicazione deve mantenere l'accesso al file, deve creare una copia e inserirla nel contenitore dell'applicazione.

La modalità Aperta è utile quando l'applicazione desidera collaborare con un'altra applicazione e condividere le modifiche apportate al documento con tale applicazione. La modalità di importazione viene utilizzata quando l'applicazione non vuole condividere le modifiche apportate a un documento con altre applicazioni.

Creazione di un documento esterno

Come indicato in precedenza, un'applicazione iOS 8 non ha accesso ai contenitori all'esterno del proprio contenitore di applicazioni. L'applicazione può scrivere nel proprio contenitore in locale o in un percorso temporaneo, quindi usare una modalità documento speciale per spostare il documento risultante all'esterno del contenitore dell'applicazione in una posizione scelta dall'utente.

Per spostare un documento in una posizione esterna, eseguire le operazioni seguenti:

  1. Creare prima di tutto un nuovo documento in un percorso locale o temporaneo.
  2. Creare un oggetto NSUrl che punta al nuovo documento.
  3. Aprire un nuovo controller di visualizzazione selezione documenti e passarlo NSUrl con la modalità di MoveToService .
  4. Quando l'utente sceglie una nuova posizione, il documento verrà spostato dalla posizione corrente alla nuova posizione.
  5. Un documento di riferimento verrà scritto nel contenitore dell'applicazione dell'app in modo che il file possa comunque essere accessibile tramite la creazione dell'applicazione.

Il codice seguente può essere usato per spostare un documento in una posizione esterna: var picker = new UIDocumentPickerViewController (srcURL, UIDocumentPickerMode.MoveToService);

Il documento di riferimento restituito dal processo precedente è esattamente uguale a quello creato dalla modalità aperta della selezione documenti. Tuttavia, in alcuni casi l'applicazione potrebbe voler spostare un documento senza conservare un riferimento.

Per spostare un documento senza generare un riferimento, utilizzare la ExportToService modalità . Esempio: var picker = new UIDocumentPickerViewController (srcURL, UIDocumentPickerMode.ExportToService);

Quando si usa la ExportToService modalità , il documento viene copiato nel contenitore esterno e la copia esistente viene lasciata nella posizione originale.

Estensioni del provider di documenti

Con iOS 8, Apple vuole che l'utente finale sia in grado di accedere a qualsiasi documento basato sul cloud, indipendentemente dalla posizione in cui esistono effettivamente. Per raggiungere questo obiettivo, iOS 8 fornisce un nuovo meccanismo di estensione del provider di documenti.

Che cos'è un'estensione del provider di documenti?

Semplicemente, un'estensione del provider di documenti è un modo per uno sviluppatore, o di terze parti, di fornire a un'applicazione un archivio documenti alternativo accessibile esattamente come il percorso di archiviazione iCloud esistente.

L'utente può selezionare uno di questi percorsi di archiviazione alternativi da Selezione documenti e può usare le stesse modalità di accesso (Apri, Importa, Sposta o Esporta) per lavorare con i file in tale posizione.

Questa operazione viene implementata usando due diverse estensioni:

  • Estensione selezione documenti: fornisce una sottoclasse che fornisce un'interfaccia UIViewController grafica che consente all'utente di scegliere un documento da un percorso di archiviazione alternativo. Questa sottoclasse verrà visualizzata come parte del controller di visualizzazione selezione documenti.
  • Estensione specifica file: si tratta di un'estensione non dell'interfaccia utente che gestisce effettivamente la fornitura del contenuto dei file. Queste estensioni vengono fornite tramite Coordinamento file ( NSFileCoordinator ). Si tratta di un altro caso importante in cui è necessario il coordinamento dei file.

Il diagramma seguente illustra il flusso di dati tipico quando si utilizzano le estensioni del provider di documenti:

Questo diagramma mostra il flusso di dati tipico quando si utilizzano le estensioni del provider di documenti

Il processo seguente si verifica:

  1. L'applicazione presenta un controller di selezione documenti per consentire all'utente di selezionare un file da utilizzare.
  2. L'utente seleziona un percorso di file alternativo e viene chiamata l'estensione personalizzata UIViewController per visualizzare l'interfaccia utente.
  3. L'utente seleziona un file da questo percorso e l'URL viene passato nuovamente alla selezione documenti.
  4. Selezione documenti seleziona l'URL del file e lo restituisce all'applicazione per consentire all'utente di lavorare.
  5. L'URL viene passato a File Coordinator per restituire il contenuto dei file all'applicazione.
  6. File Coordinator chiama l'estensione del provider di file personalizzata per recuperare il file.
  7. Il contenuto del file viene restituito a File Coordinator.
  8. Il contenuto del file viene restituito all'applicazione.

Sicurezza e segnalibri

Questa sezione illustra in modo rapido il funzionamento dell'accesso ai file persistenti e della sicurezza tramite Segnalibri con le estensioni del provider di documenti. A differenza del provider di documenti iCloud, che salva automaticamente i segnalibri e la sicurezza nel contenitore dell'applicazione, le estensioni del provider di documenti non fanno parte del sistema di riferimento dei documenti.

Ad esempio, in un'impostazione Enterprise che fornisce un archivio dati sicuro a livello aziendale, gli amministratori non vogliono accedere alle informazioni aziendali riservate o elaborate dai server iCloud pubblici. Pertanto, non è possibile utilizzare il sistema di riferimento documento predefinito.

Il sistema Bookmark può comunque essere usato ed è responsabilità dell'estensione del provider di file elaborare correttamente un URL con segnalibro e restituire il contenuto del documento a cui punta.

Ai fini della sicurezza, iOS 8 ha un livello di isolamento che rende persistenti le informazioni sull'applicazione a cui può accedere l'identificatore all'interno del provider di file. Si noti che tutti gli accessi ai file sono controllati da questo livello di isolamento.

Il diagramma seguente illustra il flusso di dati quando si utilizzano segnalibri e un'estensione del provider di documenti:

Questo diagramma mostra il flusso di dati quando si utilizzano segnalibri e un'estensione del provider di documenti

Il processo seguente si verifica:

  1. L'applicazione sta per entrare in background e deve mantenere lo stato. NSUrl Chiama per creare un segnalibro in un file in un archivio alternativo.
  2. NSUrl chiama l'estensione del provider di file per ottenere un URL permanente al documento.
  3. L'estensione del provider di file restituisce l'URL come stringa all'oggetto NSUrl .
  4. Aggrega NSUrl l'URL in un segnalibro e lo restituisce all'applicazione.
  5. Quando l'applicazione si attiva dall'essere in background e deve ripristinare lo stato, passa il segnalibro a NSUrl .
  6. NSUrl chiama l'estensione del provider di file con l'URL del file.
  7. Il provider di estensioni file accede al file e restituisce il percorso del file a NSUrl .
  8. Il percorso del file viene fornito in bundle con le informazioni di sicurezza e restituito all'applicazione.

Da qui, l'applicazione può accedere al file e usarlo come di consueto.

Scrittura di file

Questa sezione illustra in modo rapido come funziona la scrittura di file in un percorso alternativo con un'estensione del provider di documenti. L'applicazione iOS userà Coordinamento file per salvare le informazioni su disco all'interno del contenitore dell'applicazione. Poco dopo che il file è stato scritto correttamente, l'estensione del provider di file riceverà una notifica della modifica.

A questo punto, l'estensione del provider di file può iniziare a caricare il file nel percorso alternativo (o contrassegnare il file come dirty e che richiede il caricamento).

Creazione di nuove estensioni del provider di documenti

La creazione di nuove estensioni del provider di documenti non rientra nell'ambito di questo articolo introduttivo. Queste informazioni vengono fornite qui per mostrare che, in base alle estensioni caricate da un utente nel dispositivo iOS, un'applicazione può avere accesso alle posizioni di archiviazione documenti all'esterno della posizione iCloud fornita da Apple.

Lo sviluppatore deve essere a conoscenza di questo fatto quando si usa selezione documenti e si lavora con documenti esterni. Non devono presupporre che tali documenti siano ospitati in iCloud.

Per altre informazioni sulla creazione di un provider di Archiviazione o estensione selezione documenti, vedere il documento Introduzione alle estensioni dell'app.

Migrazione a iCloud Drive

In iOS 8 gli utenti possono scegliere di continuare a usare il sistema di documenti iCloud esistente usato nei sistemi iOS 7 (e precedenti) oppure possono scegliere di eseguire la migrazione dei documenti esistenti al nuovo meccanismo di iCloud Drive.

In Mac OS X Yosemite, Apple non fornisce la compatibilità con le versioni precedenti, quindi tutti i documenti devono essere migrati in iCloud Drive o non verranno più aggiornati tra i dispositivi.

Dopo che l'account di un utente è stato migrato in iCloud Drive, solo i dispositivi che usano iCloud Drive potranno propagare le modifiche ai documenti in tali dispositivi.

Importante

Gli sviluppatori devono tenere presente che le nuove funzionalità descritte in questo articolo sono disponibili solo se è stata eseguita la migrazione dell'account utente a iCloud Drive.

Riepilogo

Questo articolo ha illustrato le modifiche alle API iCloud esistenti necessarie per supportare iCloud Drive e il nuovo controller di visualizzazione selezione documenti. Ha trattato il coordinamento dei file e perché è importante quando si lavora con documenti basati sul cloud. Ha trattato la configurazione necessaria per abilitare i documenti basati sul cloud in un'applicazione Xamarin.iOS e ha esaminato in modo introduttivo l'uso di documenti all'esterno del contenitore di applicazioni di un'app usando il controller di visualizzazione selezione documenti.

Inoltre, questo articolo descrive brevemente le estensioni del provider di documenti e il motivo per cui lo sviluppatore deve essere a conoscenza di essi durante la scrittura di applicazioni in grado di gestire documenti basati sul cloud.