Výběr dokumentu v Xamarin.iOS

Výběr dokumentu umožňuje sdílení dokumentů mezi aplikacemi. Tyto dokumenty můžou být uložené v iCloudu nebo v jiném adresáři aplikace. Dokumenty se sdílejí prostřednictvím sady rozšíření zprostředkovatele dokumentů, které uživatel nainstaloval na své zařízení.

Vzhledem k tomu, že je obtížné udržovat dokumenty synchronizované napříč aplikacemi a cloudem, představují určité množství nezbytné složitosti.

Požadavky

K dokončení kroků uvedených v tomto článku je nutné provést následující kroky:

  • Xcode 7 a iOS 8 nebo novější – rozhraní API xcode 7 a iOS 8 nebo novější musí být nainstalovaná a nakonfigurovaná na počítači vývojáře.
  • Visual Studio nebo Visual Studio pro Mac – měla by být nainstalovaná nejnovější verze Visual Studio pro Mac.
  • Zařízení s iOSem – zařízení s iOSem 8 nebo novějším.

Změny v iCloudu

Pokud chcete implementovat nové funkce nástroje pro výběr dokumentů, provedly se ve službě iCloud společnosti Apple následující změny:

  • Daemon iCloudu byl zcela přepsaný pomocí CloudKitu.
  • Stávající funkce iCloudu se přejmenovaly na iCloud Drive.
  • Do iCloudu byla přidána podpora operačního systému Microsoft Windows.
  • Do Aplikace Mac OS Finder byla přidána složka iCloud.
  • Zařízení s iOSem mají přístup k obsahu složky Mac OS iCloud.

Důležité

Apple poskytuje nástroje , které vývojářům pomáhají správně zvládnout obecné nařízení Evropské unie o ochraně osobních údajů (GDPR).

Co je dokument?

Když odkazujete na dokument v iCloudu, jedná se o jedinou samostatnou entitu a uživatel by ji měl považovat za takovou. Uživatel může chtít dokument upravit nebo ho sdílet s jinými uživateli (například pomocí e-mailu).

Existuje několik typů souborů, které uživatel okamžitě rozpozná jako dokumenty, například stránky, hlavní příspěvek nebo čísla. ICloud se ale neomezuje na tento koncept. Například stav hry (například šachová shoda) může být považován za dokument a uložen v iCloudu. Tento soubor se dá předat mezi zařízeními uživatele a umožnit mu vyzvednout hru, kde skončila na jiném zařízení.

Práce s dokumenty

Než se ponoříte do kódu potřebného k použití nástroje pro výběr dokumentů s Xamarinem, tento článek se bude zabývat osvědčenými postupy pro práci s dokumenty iCloudu a několika úpravami stávajících rozhraní API potřebných k podpoře výběru dokumentů.

Použití koordinace souborů

Vzhledem k tomu, že soubor lze upravit z několika různých umístění, je potřeba koordinaci použít k zabránění ztrátě dat.

Using File Coordination

Podívejme se na výše uvedený obrázek:

  1. Zařízení s iOSem, které používá koordinaci souborů, vytvoří nový dokument a uloží ho do složky iCloud.
  2. iCloud uloží upravený soubor do cloudu pro distribuci do každého zařízení.
  3. Připojený Mac uvidí upravený soubor ve složce iCloudu a pomocí koordinace souborů zkopíruje změny souboru.
  4. Zařízení, které nepoužívá koordinaci souborů, provede změnu souboru a uloží ho do složky iCloud. Tyto změny se okamžitě replikují do ostatních zařízení.

Předpokládejme, že původní zařízení s iOSem nebo Mac upravovalo soubor, teď se jejich změny ztratí a přepíšou verzí souboru z nekoordovaného zařízení. Aby se zabránilo ztrátě dat, je koordinace souborů při práci s cloudovými dokumenty povinná.

Použití uiDocument

UIDocument usnadňuje práci (nebo NSDocument v systému macOS) provedením všech náročných akcí pro vývojáře. Poskytuje integrovanou koordinaci souborů s frontami na pozadí, aby se zabránilo blokování uživatelského rozhraní aplikace.

UIDocument zveřejňuje více rozhraní API vysoké úrovně, která usnadňují vývojovou snahu aplikace Xamarin pro jakýkoli účel, který vývojář vyžaduje.

Následující kód vytvoří podtřídu UIDocument pro implementaci obecného textového dokumentu, který lze použít k ukládání a načítání textu z iCloudu:

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

Výše GenericTextDocument uvedená třída se použije v tomto článku při práci s nástrojem pro výběr dokumentů a externími dokumenty v aplikaci Xamarin.iOS 8.

Asynchronní koordinace souborů

iOS 8 poskytuje několik nových funkcí pro koordinaci asynchronních souborů prostřednictvím nových rozhraní API pro koordinaci souborů. Před iOSem 8 byly všechna existující rozhraní API pro koordinaci souborů zcela synchronní. To znamenalo, že vývojář byl zodpovědný za implementaci vlastního řízení front na pozadí, aby zabránil koordinaci souborů v blokování uživatelského rozhraní aplikace.

Nová NSFileAccessIntent třída obsahuje adresu URL odkazující na soubor a několik možností pro řízení typu požadované koordinace. Následující kód ukazuje přesunutí souboru z jednoho umístění do jiného pomocí záměrů:

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

Zjišťování a výpis dokumentů

Způsob, jak zjišťovat a vypisovat dokumenty, je použití existujících NSMetadataQuery rozhraní API. Tato část se zabývá novými funkcemi přidanými k NSMetadataQuery tomu, aby práce s dokumenty byla ještě jednodušší než dříve.

Existující chování

Před iOSem 8 bylo pomalé vyzvednout změny místního souboru, NSMetadataQuery jako jsou například odstranění, vytváření a přejmenování.

NSMetadataQuery local file changes overview

V předchozím diagramu:

  1. U souborů, které již existují v kontejneru aplikace, NSMetadataQuery mají existující NSMetadata záznamy předem vytvořené a zařazované, aby byly okamžitě dostupné pro aplikaci.
  2. Aplikace vytvoří nový soubor v kontejneru aplikace.
  3. Před zobrazením změny kontejneru aplikace a vytvoření požadovaného NSMetadata záznamu dojde ke zpožděníNSMetadataQuery.

Vzhledem ke zpoždění při vytváření záznamu NSMetadata musela aplikace mít otevřené dva zdroje dat: jeden pro místní změny souborů a jeden pro cloudové změny.

Šití

V iOSu 8 NSMetadataQuery je jednodušší používat přímo s novou funkcí s názvem Stehování:

NSMetadataQuery with a new feature called Stitching

Použití stehování ve výše uvedeném diagramu:

  1. Stejně jako v případě souborů, které již existují v kontejneru aplikace, NSMetadataQuery mají existující NSMetadata záznamy předem vytvořené a zařazované.
  2. Aplikace vytvoří nový soubor v kontejneru aplikace pomocí koordinace souborů.
  3. Háček v kontejneru aplikace uvidí úpravy a volání NSMetadataQuery pro vytvoření požadovaného NSMetadata záznamu.
  4. Záznam NSMetadata se vytvoří přímo po souboru a zpřístupní se aplikaci.

Použití funkce Stehování aplikace už nemusí otevřít zdroj dat pro monitorování místních a cloudových změn souborů. Aplikace se teď může spoléhat NSMetadataQuery přímo.

Důležité

Steh funguje pouze v případě, že aplikace používá koordinaci souborů, jak je uvedeno v předchozí části. Pokud se koordinace souborů nepoužívá, rozhraní API ve výchozím nastavení používají stávající chování před iOSem 8.

Nové funkce metadat iOS 8

V iOSu 8 byly přidány NSMetadataQuery následující nové funkce:

  • NSMetatadataQuery teď může vypsat jiné než místní dokumenty uložené v cloudu.
  • Nová rozhraní API byla přidána pro přístup k informacím o metadatech v cloudových dokumentech.
  • K dispozici je nové NSUrl_PromisedItems rozhraní API, které bude mít přístup k atributům souborů, které můžou nebo nemusí mít jejich obsah k dispozici místně.
  • GetPromisedItemResourceValue Tato metoda slouží k získání informací o daném souboru nebo použití GetPromisedItemResourceValues metody k získání informací o více souborech najednou.

Byly přidány dva nové příznaky koordinace souborů pro práci s metadaty:

  • NSFileCoordinatorReadImmediatelyAvailableMetadataOnly
  • NSFileCoordinatorWriteContentIndependentMetadataOnly

S výše uvedenými příznaky nemusí být obsah souboru dokumentu k dispozici místně, aby se daly použít.

Následující segment kódu ukazuje, jak použít NSMetadataQuery dotaz na existenci konkrétního souboru a sestavit soubor, pokud neexistuje:

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

Miniatury dokumentu

Apple se domnívá, že nejlepší uživatelské prostředí při výpisu dokumentů pro aplikaci je používat náhledy. Tím se koncovým uživatelům poskytne kontext, aby mohli rychle identifikovat dokument, se kterým chtějí pracovat.

Před iOSem 8 vyžadovalo zobrazení náhledů dokumentů vlastní implementaci. Novinkou v iOSu 8 jsou atributy systému souborů, které vývojářům umožňují rychle pracovat s miniaturami dokumentu.

Načítání miniatur dokumentů

Voláním nebo metodami GetPromisedItemResourceValueNSUrl_PromisedItems se vrátí rozhraní API, a NSUrlThumbnailDictionary.GetPromisedItemResourceValues Jediný klíč, který je aktuálně v tomto slovníku NSThumbnial1024X1024SizeKey , je a jeho porovnávání UIImage.

Ukládání miniatur dokumentu

Nejjednodušší způsob, jak uložit miniaturu, je použít UIDocument. Když zavoláte metodu GetFileAttributesToWriteUIDocument a nastavíte miniaturu, automaticky se uloží, když je soubor dokumentu. Daemon iCloudu tuto změnu uvidí a rozšíří ji na iCloud. V systému Mac OS X se miniatury automaticky generují pro vývojáře pomocí modulu plug-in Rychlý vzhled.

Díky základům práce s dokumenty založenými na iCloudu spolu s úpravami stávajícího rozhraní API jsme připraveni implementovat kontroler zobrazení pro výběr dokumentů v mobilní aplikaci Xamarin iOS 8.

Povolení iCloudu v Xamarinu

Než bude možné v aplikaci Xamarin.iOS použít nástroj pro výběr dokumentů, musí být podpora iCloudu povolená jak ve vaší aplikaci, tak prostřednictvím Apple.

Následující postup popisuje proces zřizování pro iCloud.

  1. Vytvořte kontejner iCloudu.
  2. Vytvořte ID aplikace, které obsahuje službu App Service iCloudu.
  3. Vytvořte profil zřizování, který obsahuje toto ID aplikace.

Průvodce prací s funkcemi vás provede prvními dvěma kroky. Pokud chcete vytvořit zřizovací profil, postupujte podle pokynů v průvodci zřizovacím profilem .

Následující postup vás provede procesem konfigurace aplikace pro iCloud:

Postupujte následovně:

  1. Otevřete projekt v Visual Studio pro Mac nebo sadě Visual Studio.

  2. V Průzkumník řešení klikněte pravým tlačítkem myši na projekt a vyberte Možnosti.

  3. V dialogovém okně Možnosti vyberte aplikaci pro iOS, ujistěte se, že identifikátor sady odpovídá identifikátoru, který byl definován v ID aplikace vytvořené výše pro aplikaci.

  4. Vyberte podepisování balíčků pro iOS, vyberte identitu vývojáře a profil zřizování vytvořený výše.

  5. Kliknutím na tlačítko OK uložte změny a zavřete dialogové okno.

  6. Kliknutím pravým tlačítkem myši Entitlements.plist v Průzkumník řešení ho otevřete v editoru.

    Důležité

    V sadě Visual Studio možná budete muset otevřít editor nároků tak, že na něj kliknete pravým tlačítkem, vyberete Otevřít v aplikaci... a vyberete Editor seznamu vlastností.

  7. Zaškrtněte políčko Povolit iCloud , dokumenty iCloudu, úložiště klíč-hodnota a CloudKit .

  8. Ujistěte se, že kontejner existuje pro aplikaci (jak je vytvořeno výše). Příklad: iCloud.com.your-company.AppName

  9. Uložte změny souboru.

Další informace o oprávněních najdete v příručce Práce s nároky .

S výše uvedeným nastavením teď může aplikace používat cloudové dokumenty a nový kontroler zobrazení pro výběr dokumentů.

Běžný instalační kód

Než začnete s kontrolerem zobrazení pro výběr dokumentů, vyžaduje se nějaký standardní instalační kód. Začněte úpravou souboru aplikace AppDelegate.cs a nastavte, aby vypadal takto:

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

Důležité

Výše uvedený kód obsahuje kód z části Zjišťování a výpis dokumentů výše. Je zde prezentována v plném rozsahu, jak by se objevila ve skutečné aplikaci. Pro zjednodušení tento příklad funguje jenom s jedním pevně zakódovaným souborem (test.txt).

Výše uvedený kód zveřejňuje několik klávesových zkratek iCloud Drive, které usnadňují práci se zbytkem aplikace.

Dále do libovolného zobrazení nebo kontejneru zobrazení, který bude používat nástroj pro výběr dokumentů nebo práci s cloudovými dokumenty, přidejte následující kód:

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

Tím se přidá zástupce pro přístup k AppDelegate výše vytvořeným klávesovým zkratkám iCloudu.

S tímto kódem se podíváme na implementaci kontroleru zobrazení pro výběr dokumentů v aplikaci Xamarin iOS 8.

Použití kontroleru zobrazení pro výběr dokumentu

Před iOSem 8 bylo velmi obtížné získat přístup k dokumentům z jiné aplikace, protože neexistuje způsob, jak zjišťovat dokumenty mimo aplikaci z aplikace.

Existující chování

Existing Behavior overview

Pojďme se podívat na přístup k externímu dokumentu před iOSem 8:

  1. Nejprve by uživatel musel otevřít aplikaci, která původně vytvořila dokument.
  2. Je vybrán dokument a UIDocumentInteractionController slouží k odeslání dokumentu do nové aplikace.
  3. Nakonec se kopie původního dokumentu umístí do kontejneru nové aplikace.

Odsud je dokument k dispozici pro druhou aplikaci k otevření a úpravám.

Zjišťování dokumentů mimo kontejner aplikace

V iOSu 8 má aplikace snadný přístup k dokumentům mimo vlastní kontejner aplikací:

Discovering Documents Outside of an App's Container

Pomocí nového nástroje pro výběr dokumentů iCloudu ( UIDocumentPickerViewController) může aplikace pro iOS přímo zjišťovat a přistupovat mimo kontejner aplikace. Poskytuje UIDocumentPickerViewController uživateli mechanismus, jak udělit přístup ke zjištěným dokumentům a upravovat je prostřednictvím oprávnění.

Aplikace musí vyjádřit výslovný souhlas, aby se její dokumenty zobrazovaly v nástroji pro výběr dokumentů iCloudu a byly k dispozici pro ostatní aplikace, aby je mohly zjišťovat a pracovat s nimi. Pokud chcete, aby aplikace Xamarin iOS 8 sdílela svůj kontejner aplikací, upravte Info.plist ho ve standardním textovém editoru a přidejte následující dva řádky do dolní části slovníku (mezi <dict>...</dict> značky):

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

Poskytuje UIDocumentPickerViewController skvělé nové uživatelské rozhraní, které uživateli umožňuje zvolit dokumenty. Chcete-li zobrazit kontroler zobrazení pro výběr dokumentu v aplikaci Xamarin iOS 8, postupujte takto:

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

Důležité

Vývojář musí volat StartAccessingSecurityScopedResource metodu NSUrl před přístupem k externímu dokumentu. Metoda StopAccessingSecurityScopedResource musí být volána k uvolnění zámku zabezpečení ihned po načtení dokumentu.

Ukázkový výstup

Tady je příklad toho, jak by výše uvedený kód při spuštění na zařízení i Telefon zobrazoval výběr dokumentu:

  1. Uživatel spustí aplikaci a zobrazí se hlavní rozhraní:

    The main interface is displayed

  2. Uživatel klepne na tlačítko akce v horní části obrazovky a zobrazí se výzva k výběru poskytovatele dokumentů ze seznamu dostupných poskytovatelů:

    Select a Document Provider from the list of available providers

  3. Pro vybraného zprostředkovatele dokumentů se zobrazí kontroler zobrazení pro výběr dokumentu:

    The Document Picker View Controller is displayed

  4. Uživatel klepne na složku dokumentů a zobrazí jeho obsah:

    The Document Folder contents

  5. Uživatel vybere dokument a výběr dokumentu se zavře.

  6. Hlavní rozhraní se znovu zobrazí, dokument se načte z externího kontejneru a zobrazí se jeho obsah.

Skutečné zobrazení kontroleru zobrazení pro výběr dokumentu závisí na poskytovatelích dokumentů, které uživatel nainstaloval na zařízení a který režim výběru dokumentů byl implementován. Výše uvedený příklad používá režim otevření, ostatní typy režimu budou podrobně popsány níže.

Správa externích dokumentů

Jak je popsáno výše, před iOSem 8 může aplikace přistupovat pouze k dokumentům, které byly součástí kontejneru aplikací. V iOSu 8 má aplikace přístup k dokumentům z externích zdrojů:

Managing External Documents overview

Když uživatel vybere dokument z externího zdroje, zapíše se referenční dokument do kontejneru aplikace, který odkazuje na původní dokument.

Aby bylo možné tuto novou schopnost přidat do stávajících aplikací, bylo do NSMetadataQuery rozhraní API přidáno několik nových funkcí. Aplikace obvykle používá všudypřítomný obor dokumentu k výpisu dokumentů, které žijí v rámci kontejneru aplikace. Při použití tohoto oboru se budou dál zobrazovat pouze dokumenty v kontejneru aplikace.

Při použití nového všudypřítomného externího oboru dokumentu se vrátí dokumenty, které se nacházejí mimo kontejner aplikace, a vrátí pro ně metadata. Odkazuje NSMetadataItemUrlKey na adresu URL, kde se dokument skutečně nachází.

Někdy aplikace nechce pracovat s dokumenty, na které odkazuje odkaz. Místo toho chce aplikace pracovat s referenčním dokumentem přímo. Aplikace může například chtít zobrazit dokument ve složce aplikace v uživatelském rozhraní nebo umožnit uživateli přesouvat odkazy uvnitř složky.

V iOSu 8 je k dispozici nový NSMetadataItemUrlInLocalContainerKey dokument pro přímý přístup k referenčnímu dokumentu. Tento klíč odkazuje na skutečný odkaz na externí dokument v kontejneru aplikace.

Slouží NSMetadataUbiquitousItemIsExternalDocumentKey k otestování, jestli je dokument externí pro kontejner aplikace. Slouží NSMetadataUbiquitousItemContainerDisplayNameKey k přístupu k názvu kontejneru, který obsahuje původní kopii externího dokumentu.

Proč jsou odkazy na dokumenty povinné

Hlavním důvodem, proč iOS 8 používá odkazy na přístup k externím dokumentům, je zabezpečení. Žádná aplikace nemá přístup k kontejneru žádné jiné aplikace. To může udělat jenom výběr dokumentu, protože dochází k procesu a má přístup k celému systému.

Jediným způsobem, jak se dostat k dokumentu mimo kontejner aplikace, je použití nástroje pro výběr dokumentu a pokud je adresa URL vrácená výběrem obor zabezpečení. Adresa URL s vymezeným oborem zabezpečení obsahuje jenom dostatek informací k výběru dokumentu spolu s vymezenými právy potřebnými k udělení přístupu k dokumentu aplikacím.

Je důležité si uvědomit, že pokud byla adresa URL s vymezeným oborem zabezpečení serializována do řetězce a pak byla de-serializována, informace o zabezpečení by byly ztraceny a soubor by byl nepřístupný z adresy URL. Funkce Odkaz na dokument poskytuje mechanismus pro návrat k souborům, na které odkazují tyto adresy URL.

Takže pokud aplikace získá některou NSUrl z referenčních dokumentů, má již připojený obor zabezpečení a lze ho použít pro přístup k souboru. Z tohoto důvodu je důrazně doporučeno, aby vývojář používal UIDocument , protože zpracovává všechny tyto informace a procesy pro ně.

Použití záložek

Není vždy možné vytvořit výčet dokumentů aplikace, aby se vrátil ke konkrétnímu dokumentu, například při obnovení stavu. iOS 8 poskytuje mechanismus pro vytvoření záložek, které přímo cílí na daný dokument.

Následující kód vytvoří záložku UIDocumentFileUrl z vlastnosti:

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

Existující rozhraní API záložky slouží k vytvoření záložky proti existujícímu NSUrl , který lze uložit a načíst, aby byl zajištěn přímý přístup k externímu souboru. Následující kód obnoví záložku, která byla vytvořena výše:

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

Otevřete vs. Režim importu a výběr dokumentu.

Kontroler zobrazení pro výběr dokumentu má dva různé režimy provozu:

  1. Režim otevření – V tomto režimu, když uživatel vybere a externí dokument, výběr dokumentu vytvoří záložku s oborem zabezpečení v kontejneru aplikace.

    A Security Scoped Bookmark in the Application Container

  2. Režim importu – v tomto režimu, když uživatel vybere a externí dokument, nástroj pro výběr dokumentu nevytvoří záložku, ale místo toho zkopíruje soubor do dočasného umístění a poskytne aplikaci přístup k dokumentu v tomto umístění:

    The Document Picker will copy the file into a Temporary Location and provide the application access to the Document at this location
    Jakmile se aplikace z jakéhokoli důvodu ukončí, vyprázdní se dočasné umístění a soubor se odebere. Pokud aplikace potřebuje zachovat přístup k souboru, měla by vytvořit kopii a umístit ji do kontejneru aplikace.

Režim otevření je užitečný, když aplikace chce spolupracovat s jinou aplikací a sdílet všechny změny provedené v dokumentu s danou aplikací. Režim importu se používá, když aplikace nechce sdílet své úpravy dokumentu s jinými aplikacemi.

Vytvoření externího dokumentu

Jak je uvedeno výše, aplikace pro iOS 8 nemá přístup ke kontejnerům mimo vlastní kontejner aplikace. Aplikace může zapisovat do vlastního kontejneru místně nebo do dočasného umístění a pak pomocí speciálního režimu dokumentu přesunout výsledný dokument mimo kontejner aplikace do zvoleného umístění uživatele.

Pokud chcete přesunout dokument do externího umístění, postupujte takto:

  1. Nejprve vytvořte nový dokument v místním nebo dočasném umístění.
  2. Vytvořte odkaz NSUrl na nový dokument.
  3. Otevřete nový kontroler zobrazení pro výběr dokumentů a předejte ho NSUrlMoveToService režimem .
  4. Jakmile uživatel zvolí nové umístění, dokument se přesune z aktuálního umístění do nového umístění.
  5. Referenční dokument se zapíše do kontejneru aplikací aplikace, aby k souboru stále mohl přistupovat vytvářená aplikace.

K přesunutí dokumentu do externího umístění můžete použít následující kód: var picker = new UIDocumentPickerViewController (srcURL, UIDocumentPickerMode.MoveToService);

Referenční dokument vrácený výše uvedeným procesem je úplně stejný jako dokument vytvořený režimem otevření výběru dokumentu. Existují však časy, kdy aplikace může chtít přesunout dokument, aniž by na něj odkazy.

Pokud chcete přesunout dokument bez generování odkazu, použijte ExportToService režim. Příklad: var picker = new UIDocumentPickerViewController (srcURL, UIDocumentPickerMode.ExportToService);

Při použití ExportToService režimu se dokument zkopíruje do externího kontejneru a existující kopie zůstane v původním umístění.

Rozšíření zprostředkovatele dokumentů

V iOSu 8 chce Společnost Apple, aby měl koncový uživatel přístup k libovolnému cloudovému dokumentu bez ohledu na to, kde skutečně existuje. Pro dosažení tohoto cíle poskytuje iOS 8 nový mechanismus rozšíření zprostředkovatele dokumentů.

Co je rozšíření zprostředkovatele dokumentů?

Jednoduše řečeno, rozšíření zprostředkovatele dokumentů je způsob, jak pro vývojáře nebo třetí strany poskytnout alternativnímu úložišti dokumentů aplikace, ke kterému je možné přistupovat úplně stejným způsobem jako k existujícímu umístění úložiště iCloud.

Uživatel může vybrat jedno z těchto alternativních umístění úložiště z nástroje pro výběr dokumentu a může pro práci se soubory v tomto umístění používat přesně stejné režimy přístupu (Otevřít, Importovat, Přesunout nebo Exportovat).

To se implementuje pomocí dvou různých rozšíření:

  • Rozšíření pro výběr dokumentu – poskytuje podtřídu UIViewController , která poskytuje grafické rozhraní pro uživatele k výběru dokumentu z alternativního umístění úložiště. Tato podtřída se zobrazí jako součást kontroleru zobrazení pro výběr dokumentu.
  • File Provide Extension – Jedná se o příponu bez uživatelského rozhraní, která se zabývá skutečně poskytováním obsahu souborů. Tato rozšíření jsou poskytována prostřednictvím Koordinace souborů ( NSFileCoordinator ). To je další důležitý případ, kdy je vyžadována koordinace souborů.

Následující diagram znázorňuje typický tok dat při práci s rozšířeními zprostředkovatele dokumentů:

This diagram shows the typical data flow when working with Document Provider Extensions

Dojde k následujícímu procesu:

  1. Aplikace zobrazí kontroler pro výběr dokumentu, který uživateli umožní vybrat soubor, se kterým bude pracovat.
  2. Uživatel vybere alternativní umístění souboru a volá se vlastní UIViewController přípona, která zobrazí uživatelské rozhraní.
  3. Uživatel vybere soubor z tohoto umístění a adresa URL se předá zpět do nástroje pro výběr dokumentu.
  4. Výběr dokumentu vybere adresu URL souboru a vrátí ji do aplikace, na které má uživatel pracovat.
  5. Adresa URL se předá koordinátoru souborů a vrátí obsah souborů do aplikace.
  6. Koordinátor souborů volá vlastní příponu zprostředkovatele souborů, která soubor načte.
  7. Obsah souboru se vrátí koordinátoru souborů.
  8. Obsah souboru se vrátí do aplikace.

Zabezpečení a záložky

V této části se rychle podíváme na to, jak funguje zabezpečení a trvalý přístup k souborům prostřednictvím záložek s rozšířeními zprostředkovatele dokumentů. Na rozdíl od zprostředkovatele dokumentů iCloudu, který automaticky ukládá zabezpečení a záložky do kontejneru aplikací, rozšíření zprostředkovatele dokumentů ne, protože nejsou součástí referenčního systému dokumentů.

Příklad: V podnikovém nastavení, které poskytuje vlastní zabezpečené úložiště dat v celé společnosti, správci nechtějí, aby se k důvěrným podnikovým informacím přistupovaly nebo zpracovávaly veřejné servery iCloud. Proto nelze použít integrovaný referenční systém dokumentů.

Systém záložek je stále možné použít a je zodpovědností přípony zprostředkovatele souborů správně zpracovat záložkovanou adresu URL a vrátit obsah dokumentu, na který odkazuje.

Pro účely zabezpečení má iOS 8 vrstvu izolace, která zachovává informace o tom, která aplikace má přístup k identifikátoru, ve kterém poskytovateli souborů. Je třeba poznamenat, že veškerý přístup k souborům je řízen touto vrstvou izolace.

Následující diagram znázorňuje tok dat při práci se záložkami a rozšířením zprostředkovatele dokumentů:

This diagram shows the data flow when working with Bookmarks and a Document Provider Extension

Dojde k následujícímu procesu:

  1. Aplikace se chystá zadat pozadí a musí zachovat její stav. NSUrl Volá vytvoření záložky do souboru v alternativním úložišti.
  2. NSUrl volá příponu zprostředkovatele souborů, aby získala trvalou adresu URL dokumentu.
  3. Přípona zprostředkovatele souborů vrátí adresu URL jako řetězec .NSUrl
  4. Spojí NSUrl adresu URL do záložky a vrátí ji do aplikace.
  5. Když aplikace vzbudí z dění na pozadí a potřebuje obnovit stav, předá záložku do NSUrl .
  6. NSUrl volá příponu zprostředkovatele souborů s adresou URL souboru.
  7. Zprostředkovatel přípony souboru přistupuje k souboru a vrátí umístění souboru do NSUrl .
  8. Umístění souboru je seskupené s informacemi o zabezpečení a vráceno do aplikace.

Odtud může aplikace přistupovat k souboru a pracovat s ním jako obvykle.

Zápis souborů

V této části se dozvíte, jak funguje zápis souborů do alternativního umístění s rozšířením zprostředkovatele dokumentů. Aplikace pro iOS použije koordinaci souborů k ukládání informací na disk uvnitř kontejneru aplikace. Krátce po úspěšném zápisu souboru bude přípona zprostředkovatele souborů upozorněna na změnu.

V tomto okamžiku může přípona zprostředkovatele souborů začít nahrávat soubor do alternativního umístění (nebo soubor označit jako nezašpiněný a vyžadovat nahrání).

Vytváření nových rozšíření zprostředkovatele dokumentů

Vytváření nových rozšíření zprostředkovatele dokumentů je mimo rozsah tohoto úvodního článku. Tyto informace jsou zde uvedeny, aby ukázaly, že na základě rozšíření, která uživatel načetl do zařízení s iOSem, může mít aplikace přístup k umístěním úložiště dokumentů mimo zadané umístění iCloud společnosti Apple.

Vývojář by si měl být vědom tohoto faktu při použití nástroje pro výběr dokumentu a práci s externími dokumenty. Neměli by předpokládat, že je dokument hostovaný v iCloudu.

Další informace o vytvoření zprostředkovatele úložiště nebo rozšíření pro výběr dokumentů najdete v dokumentu Úvod k rozšířením aplikací.

Migrace na iCloud Drive

V iOSu 8 se uživatelé můžou rozhodnout, že budou dál používat stávající systém dokumentů iCloudu, který se používá v iOSu 7 (a předchozích systémech), nebo se můžou rozhodnout migrovat stávající dokumenty do nového mechanismu iCloud Drive.

V systému Mac OS X Yosemite společnost Apple neposkytuje zpětnou kompatibilitu, takže všechny dokumenty musí být migrovány na iCloud Drive nebo se už nebudou aktualizovat na všech zařízeních.

Po migraci uživatelského účtu na iCloud Drive budou moct změny v dokumentech na těchto zařízeních rozšířit jenom zařízení používající iCloud Drive.

Důležité

Vývojáři by měli vědět, že nové funkce popsané v tomto článku jsou dostupné jenom v případě, že byl uživatelský účet migrován na iCloud Drive.

Shrnutí

Tento článek popisuje změny stávajících rozhraní API iCloudu vyžadovaných pro podporu iCloudDrivu a nového kontroleru zobrazení pro výběr dokumentů. Probrala koordinaci souborů a důvod, proč je důležité při práci s cloudovými dokumenty. Probrala nastavení potřebné k povolení cloudových dokumentů v aplikaci Xamarin.iOS a při úvodním pohledu na práci s dokumenty mimo kontejner aplikace pomocí kontroleru zobrazení pro výběr dokumentů.

Kromě toho se tento článek stručně zabýval rozšířeními zprostředkovatele dokumentů a důvod, proč by o nich měl vývojář vědět při psaní aplikací, které můžou zpracovávat cloudové dokumenty.