Selektor dokumentów na platformie Xamarin.iOS
Selektor dokumentów umożliwia udostępnianie dokumentów między aplikacjami. Te dokumenty mogą być przechowywane w usłudze iCloud lub w katalogu innej aplikacji. Dokumenty są udostępniane za pośrednictwem zestawu rozszerzeń dostawcy dokumentów, które użytkownik zainstalował na swoim urządzeniu.
Ze względu na trudności z synchronizowaniem dokumentów między aplikacjami i chmurą wprowadzają pewną ilość niezbędnej złożoności.
Wymagania
Do wykonania kroków przedstawionych w tym artykule są wymagane następujące czynności:
- Xcode 7 i iOS 8 lub nowsze — na komputerze dewelopera muszą być zainstalowane i nowsze interfejsy API Xcode 7 i iOS 8 lub nowsze.
- Visual Studio lub Visual Studio dla komputerów Mac — należy zainstalować najnowszą wersję Visual Studio dla komputerów Mac.
- Urządzenie z systemem iOS — urządzenie z systemem iOS 8 lub nowszym.
Zmiany w usłudze iCloud
Aby zaimplementować nowe funkcje selektora dokumentów, wprowadzono następujące zmiany w usłudze iCloud firmy Apple:
- Demon iCloud został całkowicie przepisany przy użyciu biblioteki CloudKit.
- Nazwa istniejących funkcji usługi iCloud została zmieniona na iCloud Drive.
- Dodano obsługę systemu operacyjnego Microsoft Windows do usługi iCloud.
- Folder iCloud został dodany w narzędziu Mac OS Finder.
- Urządzenia z systemem iOS mogą uzyskiwać dostęp do zawartości folderu mac OS iCloud.
Ważne
Firma Apple udostępnia narzędzia pomagające deweloperom w prawidłowym obsłudze ogólnego rozporządzenia o ochronie danych (RODO) Unii Europejskiej.
Co to jest dokument?
W przypadku odwoływania się do dokumentu w usłudze iCloud jest to pojedyncza, autonomiczna jednostka i powinna być postrzegana jako taka przez użytkownika. Użytkownik może chcieć zmodyfikować dokument lub udostępnić go innym użytkownikom (na przykład przy użyciu poczty e-mail).
Istnieje kilka typów plików, które użytkownik natychmiast rozpozna jako dokumenty, takie jak strony, prezentacja lub pliki Numbers. Jednak usługa iCloud nie jest ograniczona do tej koncepcji. Na przykład stan gry (na przykład mecz szachowy) może być traktowany jako dokument i przechowywany w usłudze iCloud. Ten plik można przekazać między urządzeniami użytkownika i umożliwić im odbiór gry, w której została przerwana na innym urządzeniu.
Obsługa dokumentów
Przed rozpoczęciem pracy z kodem wymaganym do korzystania z selektora dokumentów za pomocą platformy Xamarin ten artykuł zawiera najlepsze rozwiązania dotyczące pracy z dokumentami usługi iCloud oraz kilka modyfikacji wprowadzonych w istniejących interfejsach API wymaganych do obsługi selektora dokumentów.
Korzystanie z koordynacji plików
Ponieważ plik można zmodyfikować z kilku różnych lokalizacji, należy użyć koordynacji, aby zapobiec utracie danych.
Przyjrzyjmy się powyższej ilustracji:
- Urządzenie z systemem iOS korzystające z koordynacji plików tworzy nowy dokument i zapisuje go w folderze iCloud.
- Usługa iCloud zapisuje zmodyfikowany plik w chmurze na potrzeby dystrybucji na każdym urządzeniu.
- Dołączony komputer Mac widzi zmodyfikowany plik w folderze iCloud i używa koordynacji plików w celu skopiowania zmian do pliku.
- Urządzenie, które nie korzysta z koordynacji plików, powoduje zmianę pliku i zapisuje je w folderze iCloud. Te zmiany są natychmiast replikowane do innych urządzeń.
Załóżmy, że oryginalne urządzenie z systemem iOS lub komputer Mac edytował plik, a teraz zmiany zostaną utracone i zastąpione wersją pliku z urządzenia niezporządkowanego. Aby zapobiec utracie danych, koordynacja plików jest wymagana podczas pracy z dokumentami opartymi na chmurze.
Korzystanie z narzędzia UIDocument
UIDocument
sprawia, że wszystko jest proste (lub NSDocument
w systemie macOS), wykonując wszystkie ciężkie zadania dla dewelopera. Zapewnia wbudowaną koordynację plików z kolejkami w tle, aby uniemożliwić blokowanie interfejsu użytkownika aplikacji.
UIDocument
Uwidacznia wiele interfejsów API wysokiego poziomu, które ułatwiają tworzenie aplikacji platformy Xamarin w dowolnym celu wymaganym przez dewelopera.
Poniższy kod tworzy podklasę UIDocument
w celu zaimplementowania ogólnego dokumentu tekstowego, który może służyć do przechowywania i pobierania tekstu z usługi 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
}
}
Klasa przedstawiona GenericTextDocument
powyżej będzie używana w tym artykule podczas pracy z selektorem dokumentów i dokumentami zewnętrznymi w aplikacji Xamarin.iOS 8.
Asynchroniczna koordynacja plików
System iOS 8 udostępnia kilka nowych funkcji asynchronicznej koordynacji plików za pośrednictwem nowych interfejsów API koordynacji plików. Przed systemem iOS 8 wszystkie istniejące interfejsy API koordynacji plików były całkowicie synchroniczne. Oznaczało to, że deweloper był odpowiedzialny za zaimplementowanie własnej kolejki w tle, aby uniemożliwić koordynację plików blokowanie interfejsu użytkownika aplikacji.
Nowa NSFileAccessIntent
klasa zawiera adres URL wskazujący plik i kilka opcji kontrolowania wymaganego typu koordynacji. Poniższy kod demonstruje przeniesienie pliku z jednej lokalizacji do innej przy użyciu intencji:
// 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);
}
});
Odnajdywanie i wyświetlanie listy dokumentów
Sposobem odnajdywania i wyświetlania listy dokumentów jest użycie istniejących NSMetadataQuery
interfejsów API. W tej sekcji omówiono nowe funkcje dodane do NSMetadataQuery
tej funkcji, dzięki czemu praca z dokumentami będzie jeszcze łatwiejsza niż wcześniej.
Istniejące zachowanie
Przed systemem iOS 8 powolne było odbieranie lokalnych zmian plików, NSMetadataQuery
takich jak: usuwanie, tworzenie i zmienianie nazw.
Na powyższym diagramie:
- W przypadku plików, które już istnieją w kontenerze aplikacji, istniejące
NSMetadata
rekordy zostały wstępnie utworzone i buforowane,NSMetadataQuery
aby były natychmiast dostępne dla aplikacji. - Aplikacja tworzy nowy plik w kontenerze aplikacji.
- Istnieje opóźnienie przed
NSMetadataQuery
sprawdzeniem modyfikacji kontenera aplikacji i utworzeniem wymaganegoNSMetadata
rekordu.
Ze względu na opóźnienie tworzenia rekordu NSMetadata
aplikacja musiała mieć otwarte dwa źródła danych: jedno dla zmian plików lokalnych i jedno dla zmian opartych na chmurze.
Szycia
W systemie iOS 8 NSMetadataQuery
łatwiej jest używać bezpośrednio z nową funkcją o nazwie Stitching:
Za pomocą łączenia na powyższym diagramie:
- Tak jak wcześniej, w przypadku plików, które już istnieją w kontenerze aplikacji,
NSMetadataQuery
istniejąceNSMetadata
rekordy zostały wstępnie utworzone i buforowane. - Aplikacja tworzy nowy plik w kontenerze aplikacji przy użyciu koordynacji plików.
- Punkt zaczepienia w kontenerze aplikacji widzi modyfikację i wywołuje metodę
NSMetadataQuery
tworzenia wymaganegoNSMetadata
rekordu. - Rekord
NSMetadata
jest tworzony bezpośrednio po pliku i jest udostępniany aplikacji.
Przy użyciu łączenia aplikacji nie trzeba już otwierać źródła danych w celu monitorowania zmian plików lokalnych i w chmurze. Teraz aplikacja może polegać bezpośrednio na NSMetadataQuery
.
Ważne
Łączenie działa tylko wtedy, gdy aplikacja korzysta z koordynacji plików, jak pokazano w powyższej sekcji. Jeśli koordynacja plików nie jest używana, interfejsy API są domyślne dla istniejącego zachowania systemu iOS 8.
Nowe funkcje metadanych systemu iOS 8
W systemie iOS 8 dodano NSMetadataQuery
następujące nowe funkcje:
NSMetatadataQuery
Program może teraz wyświetlać listę dokumentów innych niż lokalne przechowywane w chmurze.- Dodano nowe interfejsy API w celu uzyskania dostępu do informacji o metadanych w dokumentach opartych na chmurze.
- Istnieje nowy
NSUrl_PromisedItems
interfejs API, który będzie uzyskiwać dostęp do atrybutów pliku plików, które mogą lub nie mają dostępnej zawartości lokalnie. GetPromisedItemResourceValue
Użyj metody , aby uzyskać informacje o danym pliku lub użyćGetPromisedItemResourceValues
metody , aby uzyskać informacje na temat więcej niż jednego pliku jednocześnie.
Dodano dwie nowe flagi koordynacji plików do obsługi metadanych:
NSFileCoordinatorReadImmediatelyAvailableMetadataOnly
NSFileCoordinatorWriteContentIndependentMetadataOnly
Po powyższych flagach zawartość pliku dokumentu nie musi być dostępna lokalnie, aby mogły być używane.
Poniższy segment kodu pokazuje, jak używać NSMetadataQuery
do wykonywania zapytań o istnienie określonego pliku i skompilować plik, jeśli nie istnieje:
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
Firma Apple uważa, że najlepszym środowiskiem użytkownika podczas wyświetlania listy dokumentów dla aplikacji jest korzystanie z wersji zapoznawczych. Dzięki temu użytkownicy końcowi mogą szybko identyfikować dokument, z którymi chcą pracować.
Przed systemem iOS 8 wyświetlanie podglądów dokumentów wymaga implementacji niestandardowej. Nowość w systemie iOS 8 to atrybuty systemu plików, które umożliwiają deweloperowi szybką pracę z miniaturami dokumentów.
Pobieranie miniatur dokumentów
Wywołując GetPromisedItemResourceValue
metody lub GetPromisedItemResourceValues
, NSUrl_PromisedItems
interfejs API, NSUrlThumbnailDictionary
, jest zwracany. Jedynym kluczem aktualnie w tym słowniku NSThumbnial1024X1024SizeKey
jest element i jego dopasowanie UIImage
.
Zapisywanie miniatur dokumentów
Najprostszym sposobem zapisania miniatury jest użycie polecenia UIDocument
. Wywołując metodę GetFileAttributesToWrite
UIDocument
i ustawiając miniaturę, zostanie ona automatycznie zapisana po utworzeniu pliku dokumentu. Demon usługi iCloud zobaczy tę zmianę i rozpropaguje ją do usługi iCloud. W systemie Mac OS X miniatury są generowane automatycznie dla dewelopera przez wtyczkę Quick Look.
Mając podstawowe informacje na temat pracy z dokumentami opartymi na usłudze iCloud, wraz z modyfikacjami istniejącego interfejsu API, możemy zaimplementować kontroler widoku selektora dokumentów w aplikacji mobilnej platformy Xamarin iOS 8.
Włączanie usługi iCloud na platformie Xamarin
Przed użyciem selektora dokumentów w aplikacji platformy Xamarin.iOS należy włączyć obsługę usługi iCloud zarówno w aplikacji, jak i za pośrednictwem firmy Apple.
W poniższych krokach przedstawiono proces aprowizacji w usłudze iCloud.
- Utwórz kontener usługi iCloud.
- Utwórz identyfikator aplikacji zawierający usługę App Service w usłudze iCloud.
- Utwórz profil aprowizacji zawierający ten identyfikator aplikacji.
Przewodnik Praca z możliwościami zawiera instrukcje opisane w dwóch pierwszych krokach. Aby utworzyć profil aprowizacji, wykonaj kroki opisane w przewodniku Profil aprowizacji.
W poniższych krokach przedstawiono proces konfigurowania aplikacji dla usługi iCloud:
Należy wykonać następujące czynności:
Otwórz projekt w programie Visual Studio dla komputerów Mac lub Visual Studio.
W Eksplorator rozwiązań kliknij prawym przyciskiem myszy projekt i wybierz pozycję Opcje.
W oknie dialogowym Opcje wybierz pozycję Aplikacja systemu iOS, upewnij się, że identyfikator pakietu jest zgodny z identyfikatorem pakietu zdefiniowanym w identyfikatorze aplikacji utworzonym powyżej dla aplikacji.
Wybierz pozycję Podpisywanie pakietu systemu iOS, wybierz tożsamość dewelopera i utworzony powyżej profil aprowizacji.
Kliknij przycisk OK, aby zapisać zmiany i zamknąć okno dialogowe.
Kliknij prawym przyciskiem myszy
Entitlements.plist
w Eksplorator rozwiązań, aby otworzyć go w edytorze.Ważne
W programie Visual Studio może być konieczne otwarcie edytora uprawnień, klikając go prawym przyciskiem myszy, wybierając polecenie Otwórz za pomocą... i wybierając pozycję Edytor listy właściwości
Zaznacz pozycję Włącz usługę iCloud , dokumenty iCloud, magazyn klucz-wartość i zestaw CloudKit.
Upewnij się, że kontener istnieje dla aplikacji (jak utworzono powyżej). Przykład:
iCloud.com.your-company.AppName
Zapisz zmiany w pliku.
Aby uzyskać więcej informacji na temat uprawnień, zapoznaj się z przewodnikiem Praca z upoważnieniami .
Po zakończeniu powyższej konfiguracji aplikacja może teraz używać dokumentów w chmurze i nowego kontrolera widoku selektora dokumentów.
Wspólny kod konfiguracji
Przed rozpoczęciem pracy z kontrolerem widoku selektora dokumentów wymagany jest standardowy kod konfiguracji. Zacznij od zmodyfikowania pliku aplikacji AppDelegate.cs
i utwórz go w następujący sposób:
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
}
}
Ważne
Powyższy kod zawiera kod z powyższej sekcji Odnajdywanie i wyświetlanie dokumentów. Jest on przedstawiony tutaj w całości, jak to się wydaje w rzeczywistej aplikacji. Dla uproszczenia ten przykład działa tylko z pojedynczym, zakodowanym plikiem (test.txt
).
Powyższy kod uwidacznia kilka skrótów do dysku iCloud, aby ułatwić pracę w pozostałej części aplikacji.
Następnie dodaj następujący kod do dowolnego kontenera widoku lub widoku, który będzie korzystał z selektora dokumentów lub pracy z dokumentami opartymi na chmurze:
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
Spowoduje to dodanie skrótu w celu uzyskania dostępu do skrótów utworzonych powyżej i uzyskiwania dostępu do AppDelegate
skrótów w usłudze iCloud.
W tym kodzie przyjrzyjmy się implementacji kontrolera widoku selektora dokumentów w aplikacji Xamarin iOS 8.
Korzystanie z kontrolera widoku selektora dokumentów
Przed systemem iOS 8 bardzo trudno było uzyskać dostęp do dokumentów z innej aplikacji, ponieważ nie było możliwości odnajdywania dokumentów spoza aplikacji z poziomu aplikacji.
Istniejące zachowanie
Przyjrzyjmy się uzyskiwaniu dostępu do dokumentu zewnętrznego przed systemem iOS 8:
- Najpierw użytkownik musiałby otworzyć aplikację, która pierwotnie utworzyła dokument.
- Wybrano pozycję Dokument, a
UIDocumentInteractionController
element jest używany do wysyłania dokumentu do nowej aplikacji. - Na koniec kopia oryginalnego dokumentu zostanie umieszczona w kontenerze nowej aplikacji.
W tym miejscu dokument jest dostępny dla drugiej aplikacji do otwierania i edytowania.
Odnajdywanie dokumentów poza kontenerem aplikacji
W systemie iOS 8 aplikacja może łatwo uzyskiwać dostęp do dokumentów spoza własnego kontenera aplikacji:
Przy użyciu nowego selektora dokumentów w usłudze iCloud ( UIDocumentPickerViewController
) aplikacja systemu iOS może bezpośrednio odnajdywać kontener aplikacji i uzyskiwać do nie tylko do tego kontenera aplikacji. Zapewnia UIDocumentPickerViewController
mechanizm udzielania użytkownikowi dostępu i edytowania odnalezionych dokumentów za pośrednictwem uprawnień.
Aplikacja musi wyrazić zgodę na wyświetlanie dokumentów w selektorze dokumentów w usłudze iCloud i być dostępne dla innych aplikacji do odnajdywania i pracy z nimi. Aby aplikacja Xamarin iOS 8 współużytkować swój kontener aplikacji, edytuj go Info.plist
w standardowym edytorze tekstów i dodaj następujące dwa wiersze w dolnej części słownika (między tagami <dict>...</dict>
):
<key>NSUbiquitousContainerIsDocumentScopePublic</key>
<true/>
Zapewnia UIDocumentPickerViewController
świetny nowy interfejs użytkownika, który umożliwia użytkownikowi wybór dokumentów. Aby wyświetlić kontroler widoku selektora dokumentów w aplikacji Xamarin iOS 8, wykonaj następujące czynności:
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;
}
Ważne
Deweloper musi wywołać metodę StartAccessingSecurityScopedResource
NSUrl
przed uzyskaniem dostępu do dokumentu zewnętrznego. Metoda StopAccessingSecurityScopedResource
musi zostać wywołana, aby zwolnić blokadę zabezpieczeń zaraz po załadowaniu dokumentu.
Przykładowe dane wyjściowe
Oto przykład sposobu wyświetlania powyższego kodu selektora dokumentów podczas uruchamiania na urządzeniu i Telefon:
Użytkownik uruchamia aplikację, a główny interfejs jest wyświetlany:
Użytkownik naciągnie przycisk akcji w górnej części ekranu i zostanie poproszony o wybranie dostawcy dokumentów z listy dostępnych dostawców:
Kontroler widoku selektora dokumentów jest wyświetlany dla wybranego dostawcy dokumentów:
Użytkownik naciągnie folder dokumentu, aby wyświetlić jego zawartość:
Użytkownik wybierze dokument , a selektor dokumentów zostanie zamknięty.
Główny interfejs jest odtwarzany ponownie, dokument jest ładowany z zewnętrznego kontenera i jego zawartości wyświetlanej.
Rzeczywiste wyświetlanie kontrolera widoku selektora dokumentów zależy od dostawców dokumentów, których użytkownik zainstalował na urządzeniu i który tryb selektora dokumentów został zaimplementowany. W powyższym przykładzie jest używany tryb otwierania, inne typy trybu zostaną szczegółowo omówione poniżej.
Zarządzanie dokumentami zewnętrznymi
Jak wspomniano powyżej, przed systemem iOS 8 aplikacja może uzyskiwać dostęp tylko do dokumentów, które były częścią kontenera aplikacji. W systemie iOS 8 aplikacja może uzyskiwać dostęp do dokumentów ze źródeł zewnętrznych:
Gdy użytkownik wybierze dokument ze źródła zewnętrznego, dokument referencyjny jest zapisywany w kontenerze aplikacji wskazującym oryginalny dokument.
Aby ułatwić dodawanie tej nowej możliwości do istniejących aplikacji, do interfejsu NSMetadataQuery
API dodano kilka nowych funkcji. Zazwyczaj aplikacja używa wszechobecnego zakresu dokumentów do wyświetlania dokumentów znajdujących się w kontenerze aplikacji. Korzystając z tego zakresu, będą nadal wyświetlane tylko dokumenty w kontenerze aplikacji.
Użycie nowego wszechobecnego zakresu dokumentów zewnętrznych spowoduje zwrócenie dokumentów spoza kontenera aplikacji i zwrócenie metadanych dla nich. Spowoduje NSMetadataItemUrlKey
to wskazanie adresu URL, pod którym rzeczywiście znajduje się dokument.
Czasami aplikacja nie chce pracować z dokumentami wskazywanymi przez odwołanie. Zamiast tego aplikacja chce pracować bezpośrednio z dokumentem referencyjnym. Na przykład aplikacja może chcieć wyświetlić dokument w folderze Aplikacja w interfejsie użytkownika lub zezwolić użytkownikowi na przenoszenie odwołań wewnątrz folderu.
W systemie iOS 8 udostępniono nowy NSMetadataItemUrlInLocalContainerKey
dostęp bezpośrednio do dokumentu referencyjnego. Ten klucz wskazuje rzeczywiste odwołanie do dokumentu zewnętrznego w kontenerze aplikacji.
Służy NSMetadataUbiquitousItemIsExternalDocumentKey
do testowania, czy dokument jest zewnętrzny dla kontenera aplikacji. Element NSMetadataUbiquitousItemContainerDisplayNameKey
służy do uzyskiwania dostępu do nazwy kontenera, który zawiera oryginalną kopię dokumentu zewnętrznego.
Dlaczego odwołania do dokumentów są wymagane
Głównym powodem, dla którego system iOS 8 używa odwołań do uzyskiwania dostępu do dokumentów zewnętrznych, jest bezpieczeństwo. Żadna aplikacja nie ma dostępu do kontenera innej aplikacji. Tylko selektor dokumentów może to zrobić, ponieważ kończy się proces i ma dostęp do całego systemu.
Jedynym sposobem uzyskania dostępu do dokumentu spoza kontenera aplikacji jest użycie selektora dokumentów, a adres URL zwrócony przez selektor to Zakres zabezpieczeń. Adres URL o zakresie zabezpieczeń zawiera wystarczające informacje, aby wybrać dokument wraz z prawami o określonym zakresie wymaganymi do udzielenia aplikacji dostępu do dokumentu.
Należy pamiętać, że jeśli adres URL o zakresie zabezpieczeń został zserializowany w ciągu, a następnie zdyserializowany, informacje o zabezpieczeniach zostaną utracone, a plik będzie niedostępny z adresu URL. Funkcja odwołania do dokumentu udostępnia mechanizm powrotu do plików wskazywanych przez te adresy URL.
Jeśli więc aplikacja uzyskuje element NSUrl
z jednego z dokumentów referencyjnych, ma już dołączony zakres zabezpieczeń i może służyć do uzyskiwania dostępu do pliku. Z tego powodu zdecydowanie zaleca się, aby deweloper używał UIDocument
, ponieważ obsługuje wszystkie te informacje i procesy dla nich.
Korzystanie z zakładek
Nie zawsze można wyliczyć dokumenty aplikacji, aby wrócić do określonego dokumentu, na przykład podczas przywracania stanu. System iOS 8 udostępnia mechanizm tworzenia zakładek bezpośrednio przeznaczonych dla danego dokumentu.
Poniższy kod utworzy zakładkę na podstawie UIDocument
właściwości :FileUrl
// 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);
}
Istniejący interfejs API zakładek służy do tworzenia zakładki dla istniejącej NSUrl
, którą można zapisać i załadować w celu zapewnienia bezpośredniego dostępu do pliku zewnętrznego. Poniższy kod przywróci zakładkę utworzoną powyżej:
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);
}
}
Otwórz tryb importu i selektor dokumentów
Kontroler widoku selektora dokumentów zawiera dwa różne tryby operacji:
Tryb otwierania — w tym trybie po wybraniu przez użytkownika i zewnętrznym dokumencie selektor dokumentów utworzy zakładkę z zakresem zabezpieczeń w kontenerze aplikacji.
Tryb importu — w tym trybie, gdy użytkownik wybierze i dokument zewnętrzny, selektor dokumentów nie utworzy zakładki, ale zamiast tego skopiuj plik do lokalizacji tymczasowej i zapewni aplikacji dostęp do dokumentu w tej lokalizacji:
Po zakończeniu działania aplikacji z jakiegokolwiek powodu lokalizacja tymczasowa zostanie opróżniona i plik zostanie usunięty. Jeśli aplikacja musi zachować dostęp do pliku, powinna utworzyć kopię i umieścić ją w kontenerze aplikacji.
Tryb otwierania jest przydatny, gdy aplikacja chce współpracować z inną aplikacją i udostępniać wszelkie zmiany wprowadzone w dokumencie tej aplikacji. Tryb importu jest używany, gdy aplikacja nie chce udostępniać jej modyfikacji w dokumencie innym aplikacjom.
Tworzenie dokumentu zewnętrznego
Jak wspomniano powyżej, aplikacja systemu iOS 8 nie ma dostępu do kontenerów poza własnym kontenerem aplikacji. Aplikacja może zapisywać dane we własnym kontenerze lokalnie lub w lokalizacji tymczasowej, a następnie przenosić wynikowy dokument poza kontenerem aplikacji do wybranej przez użytkownika lokalizacji.
Aby przenieść dokument do lokalizacji zewnętrznej, wykonaj następujące czynności:
- Najpierw utwórz nowy dokument w lokalizacji lokalnej lub tymczasowej.
- Utwórz element
NSUrl
wskazujący nowy dokument. - Otwórz nowy kontroler widoku selektora dokumentów i przekaż go
NSUrl
za pomocą trybuMoveToService
. - Gdy użytkownik wybierze nową lokalizację, dokument zostanie przeniesiony z bieżącej lokalizacji do nowej lokalizacji.
- Dokument referencyjny zostanie zapisany w kontenerze aplikacji aplikacji, dzięki czemu plik będzie nadal dostępny przez tworzenie aplikacji.
Poniższy kod może służyć do przenoszenia dokumentu do lokalizacji zewnętrznej: var picker = new UIDocumentPickerViewController (srcURL, UIDocumentPickerMode.MoveToService);
Dokument referencyjny zwrócony przez powyższy proces jest dokładnie taki sam jak dokument utworzony przez tryb otwierania selektora dokumentów. Jednak czasami aplikacja może chcieć przenieść dokument bez konieczności odwołowania się do niego.
Aby przenieść dokument bez generowania odwołania, użyj trybu ExportToService
. Przykład: var picker = new UIDocumentPickerViewController (srcURL, UIDocumentPickerMode.ExportToService);
W przypadku korzystania z ExportToService
trybu dokument jest kopiowany do zewnętrznego kontenera, a istniejąca kopia jest pozostawiona w oryginalnej lokalizacji.
Rozszerzenia dostawcy dokumentów
W systemie iOS 8 firma Apple chce, aby użytkownik końcowy mógł uzyskać dostęp do dowolnego z dokumentów opartych na chmurze, niezależnie od tego, gdzie rzeczywiście istnieją. Aby osiągnąć ten cel, system iOS 8 udostępnia nowy mechanizm rozszerzenia dostawcy dokumentów.
Co to jest rozszerzenie dostawcy dokumentów?
Po prostu określono, rozszerzenie dostawcy dokumentów jest sposobem dla dewelopera lub innej firmy, aby udostępnić alternatywnemu magazynowi dokumentów aplikacji, do którego można uzyskać dostęp w dokładnie taki sam sposób jak istniejąca lokalizacja magazynu iCloud.
Użytkownik może wybrać jedną z tych alternatywnych lokalizacji przechowywania z selektora dokumentów i używać dokładnie tych samych trybów dostępu (Otwórz, Importuj, Przenieś lub Eksportuj), aby pracować z plikami w tej lokalizacji.
Jest to implementowane przy użyciu dwóch różnych rozszerzeń:
- Rozszerzenie selektora dokumentów — udostępnia podklasę
UIViewController
, która udostępnia interfejs graficzny użytkownika do wyboru dokumentu z alternatywnej lokalizacji przechowywania. Ta podklasa będzie wyświetlana jako część kontrolera widoku selektora dokumentów. - Rozszerzenie Udostępniania pliku — jest to rozszerzenie inne niż interfejs użytkownika, które zajmuje się dostarczaniem zawartości plików. Te rozszerzenia są udostępniane za pośrednictwem koordynacji plików (
NSFileCoordinator
). Jest to kolejny ważny przypadek, w którym wymagana jest koordynacja plików.
Na poniższym diagramie przedstawiono typowy przepływ danych podczas pracy z rozszerzeniami dostawcy dokumentów:
Następuje następujący proces:
- Aplikacja przedstawia kontroler selektora dokumentów, aby umożliwić użytkownikowi wybranie pliku do pracy.
- Użytkownik wybiera alternatywną lokalizację pliku, a rozszerzenie niestandardowe
UIViewController
jest wywoływane w celu wyświetlenia interfejsu użytkownika. - Użytkownik wybiera plik z tej lokalizacji, a adres URL jest przekazywany z powrotem do selektora dokumentów.
- Selektor dokumentów wybiera adres URL pliku i zwraca go do aplikacji, aby użytkownik pracował.
- Adres URL jest przekazywany do koordynatora plików w celu zwrócenia zawartości plików do aplikacji.
- Koordynator plików wywołuje niestandardowe rozszerzenie dostawcy plików, aby pobrać plik.
- Zawartość pliku jest zwracana do koordynatora plików.
- Zawartość pliku jest zwracana do aplikacji.
Zabezpieczenia i zakładki
W tej sekcji przedstawiono, jak zabezpieczenia i trwały dostęp do plików za pośrednictwem zakładek współdziałają z rozszerzeniami dostawcy dokumentów. W przeciwieństwie do dostawcy dokumentów usługi iCloud, który automatycznie zapisuje zabezpieczenia i zakładki w kontenerze aplikacji, rozszerzenia dostawcy dokumentów nie są częścią systemu referencyjnego dokumentów.
Na przykład: w ustawieniu Enterprise, które udostępnia własny bezpieczny magazyn danych w całej firmie, administratorzy nie chcą, aby poufne informacje firmowe uzyskiwały dostęp do publicznych serwerów iCloud ani nie przetwarzały ich. W związku z tym nie można użyć wbudowanego systemu referencyjnego dokumentów.
System zakładek nadal może być używany i jest odpowiedzialny za poprawne przetwarzanie adresu URL zakładki i zwracanie zawartości dokumentu wskazywanego przez niego.
W celach bezpieczeństwa system iOS 8 ma warstwę izolacji, która utrwala informacje o tym, do której aplikacji ma dostęp do identyfikatora, w którym dostawcy plików. Należy zauważyć, że cały dostęp do plików jest kontrolowany przez tę warstwę izolacji.
Na poniższym diagramie przedstawiono przepływ danych podczas pracy z zakładkami i rozszerzeniem dostawcy dokumentów:
Następuje następujący proces:
- Aplikacja ma wprowadzić tło i musi utrwalić jej stan. Wywołuje
NSUrl
metodę tworzenia zakładki do pliku w magazynie alternatywnym. NSUrl
wywołuje rozszerzenie dostawcy plików, aby uzyskać trwały adres URL do dokumentu.- Rozszerzenie dostawcy plików zwraca adres URL jako ciąg do .
NSUrl
- Adres
NSUrl
URL jest dołączany do zakładki i zwraca go do aplikacji. - Gdy aplikacja obudzi się w tle i musi przywrócić stan, przekazuje zakładkę do .
NSUrl
NSUrl
wywołuje rozszerzenie dostawcy plików z adresem URL pliku.- Dostawca rozszerzenia plików uzyskuje dostęp do pliku i zwraca lokalizację pliku na
NSUrl
. - Lokalizacja pliku jest pakowana z informacjami o zabezpieczeniach i zwracana do aplikacji.
W tym miejscu aplikacja może uzyskać dostęp do pliku i pracować z nim w zwykły sposób.
Zapisywanie plików
W tej sekcji przedstawiono sposób działania zapisywania plików w lokalizacji alternatywnej za pomocą rozszerzenia dostawcy dokumentów. Aplikacja systemu iOS będzie używać koordynacji plików do zapisywania informacji na dysku wewnątrz kontenera aplikacji. Wkrótce po pomyślnym zapisaniu pliku rozszerzenie dostawcy plików zostanie powiadomione o zmianie.
W tym momencie rozszerzenie dostawcy plików może rozpocząć przekazywanie pliku do lokalizacji alternatywnej (lub oznaczyć plik jako zanieczyszczony i wymagający przekazania).
Tworzenie nowych rozszerzeń dostawcy dokumentów
Tworzenie nowych rozszerzeń dostawcy dokumentów wykracza poza zakres tego artykułu wprowadzającego. Te informacje są dostępne tutaj, aby pokazać, że na podstawie rozszerzeń załadowanych przez użytkownika na urządzeniu z systemem iOS aplikacja może mieć dostęp do lokalizacji przechowywania dokumentów poza lokalizacją usługi iCloud firmy Apple.
Deweloper powinien mieć świadomość tego faktu podczas korzystania z selektora dokumentów i pracy z dokumentami zewnętrznymi. Nie należy zakładać, że te dokumenty są hostowane w usłudze iCloud.
Aby uzyskać więcej informacji na temat tworzenia dostawcy magazynu lub rozszerzenia selektora dokumentów, zobacz dokument Wprowadzenie do rozszerzeń aplikacji.
Migrowanie do dysku w usłudze iCloud
W systemie iOS 8 użytkownicy mogą nadal korzystać z istniejącego systemu dokumentów w usłudze iCloud używanego w systemie iOS 7 (i wcześniejszych systemach) lub zdecydować się na migrację istniejących dokumentów do nowego mechanizmu usługi iCloud Drive.
W systemie Mac OS X Yosemite firma Apple nie zapewnia zgodności z poprzednimi wersjami, więc wszystkie dokumenty muszą być migrowane do usługi iCloud Drive lub nie będą już aktualizowane na urządzeniach.
Po przeprowadzeniu migracji konta użytkownika do usługi iCloud Drive tylko urządzenia korzystające z usługi iCloud Drive będą mogły propagować zmiany do dokumentów na tych urządzeniach.
Ważne
Deweloperzy powinni pamiętać, że nowe funkcje opisane w tym artykule są dostępne tylko wtedy, gdy konto użytkownika zostało zmigrowane do usługi iCloud Drive.
Podsumowanie
W tym artykule omówiono zmiany istniejących interfejsów API usługi iCloud wymaganych do obsługi usługi iCloud Drive i nowego kontrolera widoku selektora dokumentów. Omówiła koordynację plików i dlaczego jest ona ważna podczas pracy z dokumentami opartymi na chmurze. Obejmowała ona konfigurację wymaganą do włączenia dokumentów opartych na chmurze w aplikacji platformy Xamarin.iOS i biorąc pod uwagę wprowadzenie do pracy z dokumentami spoza kontenera aplikacji aplikacji przy użyciu kontrolera widoku selektora dokumentów.
Ponadto w tym artykule krótko opisano rozszerzenia dostawcy dokumentów i dlaczego deweloper powinien być świadomy ich podczas pisania aplikacji, które mogą obsługiwać dokumenty oparte na chmurze.