rozšíření pro iOS v Xamarin. iOSiOS extensions in Xamarin.iOS

Vytváření rozšíření ve videu pro iOSCreating Extensions in iOS video

Rozšíření, jak je představeno v iOS 8, jsou specializovaná v systému UIViewControllers iOS ve standardních kontextech, jako jsou například v centru oznámení, jako vlastní typy klávesnic, které uživatel požaduje k provedení specializovaného vstupu nebo jiných kontextů, jako je úprava fotografie, kde může rozšíření poskytnout speciální filtry efektu.Extensions, as introduced in iOS 8, are specialized UIViewControllers that are presented by iOS inside standard contexts such as within the Notification Center, as custom keyboard types requested by the user to perform specialized input or other contexts like editing a photo where the Extension can provide special effect filters.

Všechna rozšíření se instalují ve spojení s aplikací typu kontejner (s oběma prvky napsanými pomocí 64 sjednocených rozhraní API) a aktivují se z konkrétního bodu rozšíření v hostitelské aplikaci.All Extensions are installed in conjunction with a Container app (with both elements written using the 64-bit Unified APIs) and are activated from a particular Extension Point in a Host app. A vzhledem k tomu, že budou použity jako doplňky pro existující funkce systému, musí být vysoce výkonné, štíhlé a robustní.And since they will be used as supplements to existing system functions, they must be high performance, lean, and robust.

Rozšiřovací bodyExtension points

TypType PopisDescription Rozšiřovací bodExtension Point Hostitelská aplikaceHost App
AkceAction Specializovaný Editor nebo prohlížeč pro určitý typ médiaSpecialized editor or viewer for a particular media type com.apple.ui-services VšechnyAny
Poskytovatel dokumentuDocument Provider Umožňuje aplikaci používat vzdálené úložiště dokumentů.Allows app to use a remote document store com.apple.fileprovider-ui Aplikace využívající UIDocumentPickerViewControllerApps using a UIDocumentPickerViewController
KlávesniceKeyboard Alternativní klávesniceAlternate keyboards com.apple.keyboard-service VšechnyAny
Úpravy fotekPhoto Editing Manipulace a úpravy fotekPhoto manipulation and editing com.apple.photo-editing Fotky. app EditorPhotos.app editor
SdíletShare Sdílí data se sociálními sítěmi, službami zasílání zpráv atd.Shares data with social networks, messaging services, etc. com.apple.share-services VšechnyAny
DnesToday Widgety, které se zobrazují na obrazovce pro dnešek nebo v centru oznámení“Widgets” that appear on the Today screen or Notification Center com.apple.widget-extensions Dnes a centrum oznámeníToday and Notification Center

V iOS 10 a iOS 12se přidaly další rozšiřující body.Additional extension points were added in iOS 10 and iOS 12. Úplnou tabulku všech podporovaných typů najdete v Průvodci programováním rozšíření pro iOS App Extension.You can find the complete table of all supported types in the iOS App Extension Programming Guide.

OmezeníLimitations

Rozšíření mají několik omezení, z nichž některé jsou univerzální pro všechny typy (například bez typu rozšíření mají přístup k kamerám nebo mikrotelefonům), zatímco jiné typy rozšíření mohou mít určitá omezení na jejich použití (například vlastní klávesnice nelze použít pro pole zabezpečeného zadávání dat, například pro hesla).Extensions have a number of limitations, some of which are universal to all types (for instance, no type of Extension can access the cameras or microphones) while other types of Extension may have specific limitations on their usage (for instance, custom keyboards cannot be used for secure data entry fields such as for passwords).

Univerzální omezení jsou:The universal limitations are:

Jednotlivá omezení najdete v tématu Průvodce programováním rozšíření aplikaceod společnosti Apple.For individual limitations, please see Apple's App Extension Programming Guide.

Distribuce, instalace a spouštění rozšířeníDistributing, installing, and running extensions

Rozšíření jsou distribuována z aplikace typu kontejner, která je následně odeslána a distribuována prostřednictvím App Storu.Extensions are distributed from within a container app, which, in turn is submitted and distributed via the App Store. Rozšíření distribuovaná s aplikací jsou v tuto chvíli nainstalovaná, ale uživatel musí každé rozšíření explicitně povolit.The Extension(s) distributed with the app are installed at that point, but the user must enable each Extension explicitly. Různé typy rozšíření jsou povoleny různými způsoby. několik vyžaduje, aby uživatel přešel do aplikace Nastavení a tam tam povolil.The different types of Extensions are enabled in different ways; several require the user to navigate to the Settings app and enable them from there. I když jsou ostatní povoleni v okamžiku použití, například povolení rozšíření sdílení při odesílání fotografie.While others are enabled at point of use, such as enabling a Sharing Extension when sending a photo.

Aplikace, ve které se rozšíření používá (kde se uživatel setká s bodem rozšíření), se označuje jako Hostitelská aplikace, protože je to aplikace, která toto rozšíření hostuje, když se spustí.The app in which the Extension is used (where the user encounters the Extension Point) is referred to as the Host app, since it is the app that hosts the Extension when it executes. Aplikace, která nainstaluje rozšíření, je kontejnerová aplikace, protože se jedná o aplikaci, která rozšíření při instalaci obsahovala.The app that installs the Extension is the Container app, because it is the app that contained the Extension when it was installed.

Obvykle aplikace kontejneru popisuje rozšíření a provede uživatele procesem jeho povolení.Typically, the container app describes the extension and walks the user through the process of enabling it.

Ladit a vydávat verze rozšířeníDebug and release versions of extensions

Omezení paměti pro spuštěná rozšíření aplikace jsou výrazně nižší než omezení paměti aplikovaná na aplikaci v popředí.Memory limits for running app extensions are significantly lower than the memory limits applied to a foreground app. Simulátory se spuštěným iOS mají pro rozšíření nastavené míň omezení a rozšíření můžete spustit bez jakýchkoli problémů.Simulators running iOS have less restrictions applied to extensions, and you can execute your extension without any issues. Spuštění stejného rozšíření na zařízení ale může vést k neočekávaným výsledkům, včetně selhání rozšíření nebo jeho náhlého ukončení systémem.However, running the same extension on a device can lead to unexpected results, including the extension crashing or being aggressively terminated by the system. Proto před odesláním na zařízení nezapomeňte rozšíření sestavit a otestovat.Therefore, ensure you build and test the extension on a device before shipping it.

Měli byste zajistit, aby se pro projekt kontejneru a všechna odkazovaná rozšíření používala následující nastavení:You should ensure that the following settings are applied to the container project and all referenced extensions:

  1. Sestavení balíčku aplikace v konfiguraci vydané verze .Build a application package in Release configuration.
  2. V nastavení projektu sestavení iOS nastavte možnost chování linkeru jenom na propojování sad SDK architektury nebo propojte vše.In the iOS Build project settings, set the Linker behavior option to Link Framework SDKs Only or Link All.
  3. V nastavení projektu ladění pro iOS zrušte zaškrtnuté políčko Povolit ladění a Povolit profilování .In the iOS Debug project settings, uncheck the Enable debugging and Enable profiling option.

Životní cyklus rozšířeníExtension lifecycle

Rozšíření může být jednoduché jako jedno UIViewController nebo složitější rozšíření, která prezentují více obrazovek uživatelského rozhraní.An Extension can be as simple as a single UIViewController or more complex Extensions that present multiple screens of UI. Když uživatel narazí na rozšiřující body (například při sdílení obrázku), bude mít možnost zvolit z rozšíření registrovaných pro daný rozšiřovací bod.When the user encounters an Extension Points (such as when sharing an image), they will have an opportunity to choose from the Extensions registered for that Extension Point.

Pokud zvolí jedno z rozšíření vaší aplikace, vytvoří se jeho UIViewController instance a spustí normální životní cyklus kontroleru zobrazení.If they choose one of your app's Extensions, its UIViewController will be instantiated and begin the normal View Controller lifecycle. Nicméně na rozdíl od normální aplikace, která je pozastavená, ale ne obecně ukončena, když uživatel dokončí interakci s nimi, rozšíření se načtou, spustí a pak opakovaně ukončí.However, unlike a normal app, which are suspended but not generally terminated when the user finishes interacting with them, Extensions are loaded, executed, and then terminated repeatedly.

Rozšíření můžou komunikovat se svými hostitelskými aplikacemi prostřednictvím objektu NSExtensionContext .Extensions can communicate with their Host apps via an NSExtensionContext object. Některá rozšíření mají operace, které přijímají asynchronní zpětná volání s výsledky.Some Extensions have operations that receive asynchronous callbacks with the results. Tato zpětná volání budou provedena v vláknech na pozadí a rozšíření musí tuto funkci brát v úvahu. například pomocí nsobjectu. InvokeOnMainThread , pokud chtějí aktualizovat uživatelské rozhraní.These callbacks will be executed on background threads and the Extension must take this into consideration; for instance, by using NSObject.InvokeOnMainThread if they want to update the user interface. Další podrobnosti najdete v části komunikace s hostitelskou aplikací níže.See the Communicating with the Host App section below for more details.

Ve výchozím nastavení rozšíření a jejich kontejnerové aplikace nemůžou komunikovat, i když se instalují dohromady.By default, Extensions and their container apps can not communicate, despite being installed together. V některých případech je aplikace kontejneru v podstatě prázdným kontejnerem "doprava", jehož účelem je po instalaci rozšíření obsluhován.In some cases, the Container app is essentially an empty "shipping" container whose purpose is served once the Extension is installed. Pokud se ale nadiktují okolnosti, aplikace kontejneru a rozšíření můžou sdílet prostředky ze společné oblasti.However, if circumstances dictate, the Container app and the Extension may share resources from a common area. Kromě toho může rozšíření Today požádat svou aplikaci kontejneru, aby otevřela adresu URL.Additionally, a Today Extension may request its Container app to open a URL. Toto chování se zobrazuje v pomůckě pro odpočítávání událostí.This behavior is shown in the Event Countdown Widget.

Vytvoření rozšířeníCreating an extension

Rozšíření (a jejich kontejnerové aplikace) musí mít 64 bitů binárních souborů a sestavená pomocí sjednocených rozhraní APIXamarin. iOS.Extensions (and their Container apps) must be 64-bit binaries and built using the Xamarin.iOS Unified APIs. Při vývoji rozšíření budou vaše řešení obsahovat alespoň dva projekty: aplikaci kontejneru a jeden projekt pro každé rozšíření, které kontejner poskytuje.When developing an Extension, your solutions will contain at least two projects: the container app and one project for each Extension the container provides.

Požadavky na projekt aplikace kontejneruContainer app project requirements

Aplikace kontejneru použitá k instalaci rozšíření má následující požadavky:The Container app used to install the Extension has the following requirements:

  • Musí udržovat odkaz na projekt rozšíření.It must maintain a reference to the Extension project.
  • Musí se jednat o úplnou aplikaci (musí být schopná spustit a spustit úspěšně) i v případě, že nezpůsobí instalaci rozšíření.It must be a complete app (must be able to launch and run successfully) even if it does nothing more than provide a way to install an Extension.
  • Musí mít identifikátor sady prostředků, který je základem pro identifikátor balíčku projektu rozšíření (Další informace najdete v části níže).It must have a Bundle Identifier that is the basis for the Bundle Identifier of the Extension project (see the section below for more details).

Požadavky na projekt rozšířeníExtension project requirements

Kromě toho projekt rozšíření má následující požadavky:Additionally, the Extension's project has the following requirements:

  • Musí mít identifikátor sady prostředků, který začíná identifikátorem sady prostředků aplikace kontejneru.It must have a Bundle Identifier that starts with its Container app's Bundle Identifier. Například pokud má aplikace kontejneru identifikátor sady com.myCompany.ContainerApp , identifikátor rozšíření může být com.myCompany.ContainerApp.MyExtension :For example, if the Container app's has a Bundle Identifier of com.myCompany.ContainerApp, the Extension's identifier might be com.myCompany.ContainerApp.MyExtension:

    Identifikátory sady prostředků

  • Musí NSExtensionPointIdentifier ve svém souboru definovat klíč s odpovídající hodnotou (například com.apple.widget-extension pro widget centra oznámení v dnešní době ) Info.plist .It must define the key NSExtensionPointIdentifier, with an appropriate value (such as com.apple.widget-extension for a Today Notification Center widget), in its Info.plist file.

  • Musí také definovat buď klíč, NSExtensionMainStoryboard nebo NSExtensionPrincipalClass klíč v jeho Info.plist souboru s odpovídající hodnotou:It must also define either the NSExtensionMainStoryboard key or the NSExtensionPrincipalClass key in its Info.plist file with an appropriate value:

    • Pomocí NSExtensionMainStoryboard klíče zadejte název scénáře, který představuje hlavní uživatelské rozhraní pro rozšíření (mínus .storyboard ).Use the NSExtensionMainStoryboard key to specify the name of the Storyboard that presents the main UI for the Extension (minus .storyboard). Například Main pro Main.storyboard soubor.For example, Main for the Main.storyboard file.
    • Pomocí NSExtensionPrincipalClass klíče určete třídu, která bude inicializována při spuštění rozšíření.Use the NSExtensionPrincipalClass key to specify the class that will be initialized when the Extension is started. Hodnota se musí shodovat s hodnotou v registru vašeho UIViewController :The value must match the Register value of your UIViewController:

    Registrace hlavní třídy

Konkrétní typy rozšíření mohou mít další požadavky.Specific types of Extensions may have additional requirements. Například hlavní třída rozšíření dnešního centra nebo centra oznámení musí implementovat INCWidgetProviding.For instance, a Today or Notification Center Extension’s principal class must implement INCWidgetProviding.

Důležité

Pokud projekt zahájíte pomocí jedné šablony rozšíření, kterou poskytuje Visual Studio pro Mac, budou tyto požadavky poskytnuty a splněny pro vás automaticky šablonou.If you start your project using one the Extensions templates provided by Visual Studio for Mac, most (if not all) these requirements will be provided and met for you automatically by the template.

Názorný postupWalkthrough

V následujícím návodu vytvoříte příklad widgetu dnes , který vypočítá den a počet zbývajících dní v roce:In following walkthrough, you will create an example Today widget that calculates the day and number of days remaining in the year:

Příklad widgetu dnes, který vypočítá den a počet dní zbývajících v roceAn example Today widget that calculates the day and number of days remaining in the year

Vytváření řešeníCreating the solution

Chcete-li vytvořit požadované řešení, postupujte následovně:To create the required solution, do the following:

  1. Nejprve vytvořte nový projekt aplikace s iOS, jedním zobrazením a klikněte na tlačítko Další :First, create a new iOS, Single View App project and click the Next button:

    Nejdřív vytvořte nový projekt aplikace s iOS, jedním zobrazením a klikněte na tlačítko Další.First, create a new iOS, Single View App project and click the Next button

  2. Zavolejte na projekt TodayContainer a klikněte na tlačítko Další :Call the project TodayContainer and click the Next button:

    Zavolejte TodayContainer projektu a klikněte na tlačítko Další.Call the project TodayContainer and click the Next button

  3. Ověřte název projektu a název řešení a kliknutím na tlačítko vytvořit vytvořte řešení:Verify the Project Name and SolutionName and click the Create button to create the solution:

    Ověřte název projektu a název řešení a kliknutím na tlačítko vytvořit vytvořte řešení.Verify the Project Name and SolutionName and click the Create button to create the solution

  4. Potom v Průzkumník řešeníklikněte pravým tlačítkem na řešení a přidejte nový projekt rozšíření iOS ze šablony rozšíření dnes :Next, in the Solution Explorer, right-click on the Solution and add a new iOS Extension project from the Today Extension template:

    Potom v Průzkumník řešení klikněte pravým tlačítkem na řešení a přidejte nový projekt rozšíření iOS ze šablony rozšíření dnes.Next, in the Solution Explorer, right-click on the Solution and add a new iOS Extension project from the Today Extension template

  5. Zavolejte na projekt DaysRemaining a klikněte na tlačítko Další :Call the project DaysRemaining and click the Next button:

    Zavolejte DaysRemaining projektu a klikněte na tlačítko Další.Call the project DaysRemaining and click the Next button

  6. Zkontrolujte projekt a kliknutím na tlačítko vytvořit ho vytvořte:Review the project and click the Create button to create it:

    Zkontrolujte projekt a kliknutím na tlačítko vytvořit ho vytvořte.Review the project and click the Create button to create it

Výsledné řešení by nyní mělo mít dva projekty, jak je znázorněno zde:The resulting Solution should now have two projects, as shown here:

Výsledné řešení by teď mělo mít dva projekty, jak je vidět tady.The resulting Solution should now have two projects, as shown here

Vytvoření uživatelského rozhraní rozšířeníCreating the extension user interface

Dále budete muset navrhnout rozhraní pro widget dnešního dne .Next, you will need to design the interface for your Today widget. To lze provést buď pomocí scénáře, nebo vytvořením uživatelského rozhraní v kódu.This can either be done using a Storyboard or by creating the UI in code. Obě metody jsou podrobněji popsány níže.Both methods will be covered below in detail.

Používání scénářůUsing storyboards

Chcete-li vytvořit uživatelské rozhraní ve scénáři, udělejte toto:To build the UI with a Storyboard, do the following:

  1. V Průzkumník řešenídvakrát klikněte na soubor rozšíření projektu Main.storyboard a otevřete ho pro úpravy:In the Solution Explorer, double-click the Extension project's Main.storyboard file to open it for editing:

    Dvojím kliknutím na soubor rozšíření projekty hlavní. scénář otevřete ho pro úpravy.Double-click the Extension projects Main.storyboard file to open it for editing

  2. Vyberte popisek, který se automaticky přidal do uživatelského rozhraní podle šablony, a pojmenujte ho na TodayMessage kartě pomůcka v Průzkumníkovi vlastností:Select the Label that was automatically added to the UI by template and give it the Name TodayMessage in the Widget tab of the Properties Explorer:

    Vyberte popisek, který se automaticky přidal do uživatelského rozhraní podle šablony a pojmenujte ho TodayMessage na kartě pomůcka v Průzkumníkovi vlastností.Select the Label that was automatically added to the UI by template and give it the Name TodayMessage in the Widget tab of the Properties Explorer

  3. Uložte změny do scénáře.Save the changes to the Storyboard.

Použití kóduUsing code

Chcete-li vytvořit uživatelské rozhraní v kódu, postupujte následovně:To build the UI in code, do the following:

  1. V Průzkumník řešenívyberte projekt DaysRemaining , přidejte novou třídu a zavolejte ji CodeBasedViewController :In the Solution Explorer, select the DaysRemaining project, add a new class and call it CodeBasedViewController:

    Aelect projekt DaysRemaining, přidejte novou třídu a zavolejte ji CodeBasedViewControllerAelect the DaysRemaining project, add a new class and call it CodeBasedViewController

  2. Znovu v Průzkumník řešeníotevřete soubor rozšíření dvojitým kliknutím a Info.plist otevřete ho pro úpravy:Again, in the Solution Explorer, double-click Extension's Info.plist file to open it for editing:

    Dvojím kliknutím na rozšíření soubor info. plist ho otevřete pro úpravy.Double-click Extensions Info.plist file to open it for editing

  3. Vyberte zobrazení zdroje (z dolní části obrazovky) a otevřete NSExtension uzel:Select the Source View (from the bottom of the screen) and open the NSExtension node:

    V dolní části obrazovky vyberte zobrazení zdroje a otevřete uzel NSExtensionSelect the Source View from the bottom of the screen and open the NSExtension node

  4. Odeberte NSExtensionMainStoryboard klíč a přidejte NSExtensionPrincipalClass s hodnotou CodeBasedViewController :Remove the NSExtensionMainStoryboard key and add a NSExtensionPrincipalClass with the value CodeBasedViewController:

    Odeberte klíč NSExtensionMainStoryboard a přidejte NSExtensionPrincipalClass s hodnotou CodeBasedViewControllerRemove the NSExtensionMainStoryboard key and add a NSExtensionPrincipalClass with the value CodeBasedViewController

  5. Uložte provedené změny.Save your changes.

V dalším kroku upravte CodeBasedViewController.cs soubor a nastavte jeho vzhled jako na následující:Next, edit the CodeBasedViewController.cs file and make it look like the following:

using System;
using Foundation;
using UIKit;
using NotificationCenter;
using CoreGraphics;

namespace DaysRemaining
{
  [Register("CodeBasedViewController")]
  public class CodeBasedViewController : UIViewController, INCWidgetProviding
  {
    public CodeBasedViewController ()
    {
    }

    public override void ViewDidLoad ()
    {
      base.ViewDidLoad ();

      // Add label to view
      var TodayMessage = new UILabel (new CGRect (0, 0, View.Frame.Width, View.Frame.Height)) {
        TextAlignment = UITextAlignment.Center
      };

      View.AddSubview (TodayMessage);

      // Insert code to power extension here...

    }
  }
}

Všimněte si, že [Register("CodeBasedViewController")] odpovídá hodnotě, kterou jste zadali pro NSExtensionPrincipalClass výše.Note that the [Register("CodeBasedViewController")] matches the value that you specified for the NSExtensionPrincipalClass above.

Kódování rozšířeníCoding the extension

Pomocí vytvořeného uživatelského rozhraní otevřete TodayViewController.cs CodeBasedViewController.cs soubor nebo (na základě metody použité k vytvoření uživatelského rozhraní výše), změňte metodu ViewDidLoad a nastavte ji tak, aby vypadala takto:With the User Interface created, open either the TodayViewController.cs or the CodeBasedViewController.cs file (based of the method used to create the User Interface above), change the ViewDidLoad method and make it look like the following:

public override void ViewDidLoad ()
{
  base.ViewDidLoad ();

  // Calculate the values
  var dayOfYear = DateTime.Now.DayOfYear;
  var leapYearExtra = DateTime.IsLeapYear (DateTime.Now.Year) ? 1 : 0;
  var daysRemaining = 365 + leapYearExtra - dayOfYear;

  // Display the message
  if (daysRemaining == 1) {
    TodayMessage.Text = String.Format ("Today is day {0}. There is one day remaining in the year.", dayOfYear);
  } else {
    TodayMessage.Text = String.Format ("Today is day {0}. There are {1} days remaining in the year.", dayOfYear, daysRemaining);
  }
}

Pokud používáte metodu uživatelského rozhraní založenou na kódu, nahraďte // Insert code to power extension here... Komentář novým kódem z výše uvedeného.If using the code based User Interface method, replace the // Insert code to power extension here... comment with the new code from above. Po volání základní implementace (a vložení popisku pro verzi založenou na kódu) Tento kód provede jednoduchý výpočet, který získá den v roce a počet zbývajících dní.After calling the base implementation (and inserting a Label for the code based version), this code does a simple calculation to get the day of the year and how many days are remaining. Pak zobrazí zprávu v popisku ( TodayMessage ), který jste vytvořili v návrhu uživatelského rozhraní.Then it displays the message in the Label (TodayMessage) that you created in the UI design.

Všimněte si, jak podobný tento proces je normální proces psaní aplikace.Note how similar this process is to the normal process of writing an app. Rozšíření UIViewController má stejný životní cyklus jako kontroler zobrazení v aplikaci, s výjimkou rozšíření, která nemají režimy na pozadí a nejsou pozastavena, pokud je uživatel dokončí jejich používáním.An Extension's UIViewController has the same lifecycle as a View Controller in an app, except Extensions do not have background modes and are not suspended when the user is finished using them. Místo toho jsou rozšíření opakovaně inicializována a v případě potřeby zrušeno.Instead, Extensions are repeatedly initialized and de-allocated as required.

Vytvoření uživatelského rozhraní aplikace kontejneruCreating the container app user interface

Pro účely tohoto návodu se aplikace typu kontejner používá jednoduše jako metoda pro dodávání a instalaci rozšíření a neposkytuje vlastní funkce.For this walkthrough, the container app is simply used as a method to ship and install the Extension and provides no functionality of its own. Upravte Main.storyboard soubor TodayContainer a přidejte nějaký text definující funkci rozšíření a nainstalujte ho:Edit the TodayContainer's Main.storyboard file and add some text defining the Extension's function and how to install it:

Upravte soubor TodayContainers Main. scénář a přidejte nějaký text definující funkci rozšíření a nainstalujte ji.Edit the TodayContainers Main.storyboard file and add some text defining the Extensions function and how to install it

Uložte změny do scénáře.Save the changes to the Storyboard.

Testování rozšířeníTesting the extension

K otestování rozšíření v simulátoru iOS spusťte aplikaci TodayContainer .To test your Extension in the iOS Simulator, run the TodayContainer app. Zobrazí se hlavní zobrazení kontejneru:The container's main view will be displayed:

Zobrazí se hlavní zobrazení kontejnerů.The containers main view will be displayed

Dále stiskněte tlačítko Domů v simulátoru, potáhnutím dolů v horní části obrazovky otevřete Centrum oznámení, vyberte kartu Today a klikněte na tlačítko Upravit :Next, hit the Home button in the Simulator, swipe down from the top of the screen to open the Notification Center, select the Today tab and click the Edit button:

V simulátoru stiskněte tlačítko domů, potáhnutím dolů v horní části obrazovky otevřete Centrum oznámení, vyberte kartu Today a klikněte na tlačítko Upravit.Hit the Home button in the Simulator, swipe down from the top of the screen to open the Notification Center, select the Today tab and click the Edit button

Přidejte rozšíření DaysRemaining do zobrazení dnes a klikněte na tlačítko Hotovo :Add the DaysRemaining Extension to the Today view and click the Done button:

Přidejte rozšíření DaysRemaining do zobrazení dnes a klikněte na tlačítko Hotovo.Add the DaysRemaining Extension to the Today view and click the Done button

Nový widget se přidá do zobrazení dnes a zobrazí se výsledky:The new widget will be added to the Today view and the results will be displayed:

Nový widget se přidá do zobrazení dnes a zobrazí se výsledky.The new widget will be added to the Today view and the results will be displayed

Komunikace s hostitelskou aplikacíCommunicating with the host app

Ukázkové rozšíření dnes, které jste vytvořili výše, nekomunikuje s hostitelskou aplikací (obrazovka dnešní den ).The example Today Extension you created above does not communicate with its host app (the Today screen). Pokud to bylo, použije vlastnost ExtensionContext TodayViewController CodeBasedViewController třídy nebo.If it did, it would use the ExtensionContext property of the TodayViewController or CodeBasedViewController classes.

U rozšíření, která budou přijímat data ze svých hostitelských aplikací, jsou data ve formě pole NSExtensionItem objektů uložených ve vlastnosti InputItems ExtensionContext rozšíření UIViewController .For Extensions that will receive data from their host apps, the data is in the form of an array of NSExtensionItem objects stored in the InputItems property of the ExtensionContext of the Extension's UIViewController.

Jiná rozšíření, například rozšíření pro úpravy fotek, mohou rozlišovat mezi uživatelem, který dokončuje nebo ruší používání.Other Extensions, such as Photo Editing extensions, may distinguish between the user completing or canceling usage. Tato možnost se pošle zpět do hostitelské aplikace pomocí CompleteRequest a CancelRequest metod ExtensionContext .This will be signaled back to the host app via the CompleteRequest and CancelRequest methods of ExtensionContext property.

Další informace najdete v tématu Průvodce programováním rozšíření aplikaceod společnosti Apple.For more information, please see Apple's App Extension Programming Guide.

Komunikace s nadřazenou aplikacíCommunicating with the parent app

Skupina aplikací umožňuje různým aplikacím (nebo aplikacím a jejím rozšířením) přístup k umístění úložiště sdíleného souboru.An App Group allows different applications (or an application and its extensions) to access a shared file storage location. Skupiny aplikací se dají použít pro data, jako jsou:App Groups can be used for data like:

Další informace najdete v tématu věnovaném práci s funkcemi v části skupiny aplikací .For more information, please see the App Groups section of our Working with Capabilities documentation.

MobileCoreServicesMobileCoreServices

Při práci s rozšířeními použijte jednotný identifikátor typu (identifikátor UTI) k vytvoření a manipulaci s daty, která se vyměňují mezi aplikací, jinými aplikacemi a službami.When working with extensions, use a Uniform Type Identifier (UTI) to create and manipulate data that is exchanged between the app, other apps and/or services.

MobileCoreServices.UTTypeStatická třída definuje následující pomocné vlastnosti, které se vztahují na definice společnosti Apple kUTType... :The MobileCoreServices.UTType static class defines the following helper properties that relate to Apple's kUTType... definitions:

  • kUTTypeAlembic - Alembic
  • kUTTypeAliasFile - AliasFile
  • kUTTypeAliasRecord - AliasRecord
  • kUTTypeAppleICNS - AppleICNS
  • kUTTypeAppleProtectedMPEG4Audio - AppleProtectedMPEG4Audio
  • kUTTypeAppleProtectedMPEG4Video - AppleProtectedMPEG4Video
  • kUTTypeAppleScript - AppleScript
  • kUTTypeApplication - Application
  • kUTTypeApplicationBundle - ApplicationBundle
  • kUTTypeApplicationFile - ApplicationFile
  • kUTTypeArchive - Archive
  • kUTTypeAssemblyLanguageSource - AssemblyLanguageSource
  • kUTTypeAudio - Audio
  • kUTTypeAudioInterchangeFileFormat - AudioInterchangeFileFormat
  • kUTTypeAudiovisualContent - AudiovisualContent
  • kUTTypeAVIMovie - AVIMovie
  • kUTTypeBinaryPropertyList - BinaryPropertyList
  • kUTTypeBMP - BMP
  • kUTTypeBookmark - Bookmark
  • kUTTypeBundle - Bundle
  • kUTTypeBzip2Archive - Bzip2Archive
  • kUTTypeCalendarEvent - CalendarEvent
  • kUTTypeCHeader - CHeader
  • kUTTypeCommaSeparatedText - CommaSeparatedText
  • kUTTypeCompositeContent - CompositeContent
  • kUTTypeConformsToKey - ConformsToKey
  • kUTTypeContact - Contact
  • kUTTypeContent - Content
  • kUTTypeCPlusPlusHeader - CPlusPlusHeader
  • kUTTypeCPlusPlusSource - CPlusPlusSource
  • kUTTypeCSource - CSource
  • kUTTypeData - Database
  • kUTTypeDelimitedText - DelimitedText
  • kUTTypeDescriptionKey - DescriptionKey
  • kUTTypeDirectory - Directory
  • kUTTypeDiskImage - DiskImage
  • kUTTypeElectronicPublication - ElectronicPublication
  • kUTTypeEmailMessage - EmailMessage
  • kUTTypeExecutable - Executable
  • kUTExportedTypeDeclarationsKey - ExportedTypeDeclarationsKey
  • kUTTypeFileURL - FileURL
  • kUTTypeFlatRTFD - FlatRTFD
  • kUTTypeFolder - Folder
  • kUTTypeFont - Font
  • kUTTypeFramework - Framework
  • kUTTypeGIF - GIF
  • kUTTypeGNUZipArchive - GNUZipArchive
  • kUTTypeHTML - HTML
  • kUTTypeICO - ICO
  • kUTTypeIconFileKey - IconFileKey
  • kUTTypeIdentifierKey - IdentifierKey
  • kUTTypeImage - Image
  • kUTImportedTypeDeclarationsKey - ImportedTypeDeclarationsKey
  • kUTTypeInkText - InkText
  • kUTTypeInternetLocation - InternetLocation
  • kUTTypeItem - Item
  • kUTTypeJavaArchive - JavaArchive
  • kUTTypeJavaClass - JavaClass
  • kUTTypeJavaScript - JavaScript
  • kUTTypeJavaSource - JavaSource
  • kUTTypeJPEG - JPEG
  • kUTTypeJPEG2000 - JPEG2000
  • kUTTypeJSON - JSON
  • kUTType3dObject - k3dObject
  • kUTTypeLivePhoto - LivePhoto
  • kUTTypeLog - Log
  • kUTTypeM3UPlaylist - M3UPlaylist
  • kUTTypeMessage - Message
  • kUTTypeMIDIAudio - MIDIAudio
  • kUTTypeMountPoint - MountPoint
  • kUTTypeMovie - Movie
  • kUTTypeMP3 - MP3
  • kUTTypeMPEG - MPEG
  • kUTTypeMPEG2TransportStream - MPEG2TransportStream
  • kUTTypeMPEG2Video - MPEG2Video
  • kUTTypeMPEG4 - MPEG4
  • kUTTypeMPEG4Audio - MPEG4Audio
  • kUTTypeObjectiveCPlusPlusSource - ObjectiveCPlusPlusSource
  • kUTTypeObjectiveCSource - ObjectiveCSource
  • kUTTypeOSAScript - OSAScript
  • kUTTypeOSAScriptBundle - OSAScriptBundle
  • kUTTypePackage - Package
  • kUTTypePDF - PDF
  • kUTTypePerlScript - PerlScript
  • kUTTypePHPScript - PHPScript
  • kUTTypePICT - PICT
  • kUTTypePKCS12 - PKCS12
  • kUTTypePlainText - PlainText
  • kUTTypePlaylist - Playlist
  • kUTTypePluginBundle - PluginBundle
  • kUTTypePNG - PNG
  • kUTTypePolygon - Polygon
  • kUTTypePresentation - Presentation
  • kUTTypePropertyList - PropertyList
  • kUTTypePythonScript - PythonScript
  • kUTTypeQuickLookGenerator - QuickLookGenerator
  • kUTTypeQuickTimeImage - QuickTimeImage
  • kUTTypeQuickTimeMovie - QuickTimeMovie
  • kUTTypeRawImage - RawImage
  • kUTTypeReferenceURLKey - ReferenceURLKey
  • kUTTypeResolvable - Resolvable
  • kUTTypeRTF - RTF
  • kUTTypeRTFD - RTFD
  • kUTTypeRubyScript - RubyScript
  • kUTTypeScalableVectorGraphics - ScalableVectorGraphics
  • kUTTypeScript - Script
  • kUTTypeShellScript - ShellScript
  • kUTTypeSourceCode - SourceCode
  • kUTTypeSpotlightImporter - SpotlightImporter
  • kUTTypeSpreadsheet - Spreadsheet
  • kUTTypeStereolithography - Stereolithography
  • kUTTypeSwiftSource - SwiftSource
  • kUTTypeSymLink - SymLink
  • kUTTypeSystemPreferencesPane - SystemPreferencesPane
  • kUTTypeTabSeparatedText - TabSeparatedText
  • kUTTagClassFilenameExtension - TagClassFilenameExtension
  • kUTTagClassMIMEType - TagClassMIMEType
  • kUTTypeTagSpecificationKey - TagSpecificationKey
  • kUTTypeText - Text
  • kUTType3DContent - ThreeDContent
  • kUTTypeTIFF - TIFF
  • kUTTypeToDoItem - ToDoItem
  • kUTTypeTXNTextAndMultimediaData - TXNTextAndMultimediaData
  • kUTTypeUniversalSceneDescription - UniversalSceneDescription
  • kUTTypeUnixExecutable - UnixExecutable
  • kUTTypeURL - URL
  • kUTTypeURLBookmarkData - URLBookmarkData
  • kUTTypeUTF16ExternalPlainText - UTF16ExternalPlainText
  • kUTTypeUTF16PlainText - UTF16PlainText
  • kUTTypeUTF8PlainText - UTF8PlainText
  • kUTTypeUTF8TabSeparatedText - UTF8TabSeparatedText
  • kUTTypeVCard - VCard
  • kUTTypeVersionKey - VersionKey
  • kUTTypeVideo - Video
  • kUTTypeVolume - Volume
  • kUTTypeWaveformAudio - WaveformAudio
  • kUTTypeWebArchive - WebArchive
  • kUTTypeWindowsExecutable - WindowsExecutable
  • kUTTypeX509Certificate - X509Certificate
  • kUTTypeXML - XML
  • kUTTypeXMLPropertyList - XMLPropertyList
  • kUTTypeXPCService - XPCService
  • kUTTypeZipArchive - ZipArchive

Prohlédněte si následující příklad:See the following example:

using MobileCoreServices;
...

NSItemProvider itemProvider = new NSItemProvider ();
itemProvider.LoadItem(UTType.PropertyList ,null, (item, err) => {
    if (err == null) {
        NSDictionary results = (NSDictionary )item;
        NSString baseURI =
results.ObjectForKey("NSExtensionJavaScriptPreprocessingResultsKey");
    }
});

Další informace najdete v tématu věnovaném práci s funkcemi v části skupiny aplikací .For more information, please see the App Groups section of our Working with Capabilities documentation.

Bezpečnostní opatření a požadavkyPrecautions and considerations

Rozšíření mají pro ně mnohem méně dostupné paměti než aplikace.Extensions have significantly less memory available to them than apps do. Očekává se, že budou fungovat rychle a s minimálním vniknutím uživatele a aplikace, na které se hostuje.They are expected to perform rapidly and with minimal intrusion to the user and the app they are hosted in. Rozšíření by ale mělo také poskytovat odlišnou, užitečnou funkci pro náročné aplikace s uživatelským ROZHRANÍm, které umožňuje uživateli identifikovat vývojářská aplikace nebo aplikaci typu kontejner, ke kterým patří.However, an Extension should also provide a distinctive, useful function to the consuming app with a branded UI that allow the user to identify the Extension's developer or Container app they belong to.

Vzhledem k tomuto těsnému požadavku byste měli nasadit jenom rozšíření, která byla důkladně testována a optimalizována pro výkon a spotřebu paměti.Given these tight requirement, you should only deploy Extensions that have been thoroughly tested and optimized for performance and memory consumption.

SouhrnSummary

Tento dokument obsahuje rozšíření, co jsou, typ rozšiřovacích bodů a známá omezení na rozšíření pro iOS.This document has covered Extensions, what they are, the type of Extension Points and the known limitations imposed on an Extension by iOS. Popisuje vytváření, distribuci, instalaci a spouštění rozšíření a životního cyklu rozšíření.It discussed creating, distributing, installing and running Extensions and the Extension lifecycle. Poskytli jsme návod k vytvoření jednoduchého widgetu dnešního dne ukazující dva způsoby, jak vytvořit uživatelské rozhraní pomůcky pomocí scénářů nebo kódu.It provided a walkthrough of creating a simple Today widget showing two ways to create the widget's UI using either Storyboards or code. Ukázal, jak otestovat rozšíření v simulátoru iOS.It showed how to test an extension in the iOS Simulator. Nakonec stručně popisuje komunikaci s hostitelskou aplikací a několik preventivních a důležitých opatření, která by měla být při vývoji rozšíření provedena.Finally, it briefly discussed communicating with the Host App and a few precautions and considerations that should be taken when developing an extension.