Výukový program o rozšířeních aplikací pro iOS 8

Málokdo to zkoušel dříve (podívejte se na to), ale byl to právě Apple s prvním iPhonem, kdo definoval, jak má vypadat chytrý telefon a mobilní operační systém. Apple udělal neuvěřitelný průlom v oblasti hardwaru a uživatelského prostředí. Často však zapomínáme, že také stanovili standardy, jak by měl fungovat mobilní operační systém a jak by měly být vytvořeny aplikace pro Smartphone.

Vybudování betonových zdí mezi aplikacemi, aby byly zcela izolované a navzájem o sobě nevěděly, byla nejlepší metoda, jak je zabezpečit a ochránit jejich data. Veškeré činnosti byly systémem iOS pečlivě monitorovány a existovalo jen několik málo akcí, které mohla aplikace provést mimo svou působnost.

„Abstinence je nejlepší ochranou!“. – ale kde je v tom ta zábava?“

Trvalo jim to nějakou dobu; podle mě až příliš dlouho, ale s iOS 8 se Apple rozhodl, že se trochu pobaví. iOS 8 zavedl nový koncept nazvaný App Extensions. Tato nová funkce sice nezbořila zdi mezi aplikacemi, ale otevřela několik dveří poskytujících jemný, ale hmatatelný kontakt mezi některými aplikacemi. Poslední aktualizace dala vývojářům iOS možnost přizpůsobit si ekosystém iOS a my se těšíme, že se otevře i tato cesta.

Co jsou rozšíření aplikací v iOS 8 a jak fungují?“

Zjednodušeně řečeno, rozšíření aplikací v iOS 8 poskytují nový způsob interakce s aplikací, aniž by ji bylo nutné spouštět nebo zobrazovat na obrazovce.

Jak se dalo očekávat, Apple si dal záležet na tom, aby zůstal nad věcí, takže existuje jen hrstka nových vstupních bodů, které může vaše aplikace poskytovat:

  • Dnes (nazývané také widget) – rozšíření zobrazené v zobrazení Dnes v oznamovacím centru zobrazuje stručné informace a umožňuje provádět rychlé úkoly.
  • Sdílení – rozšíření, které umožňuje vaší aplikaci sdílet obsah s uživateli na sociálních sítích a v dalších službách sdílení.
  • Akce – rozšíření, které umožňuje vytvářet vlastní akční tlačítka v listu Akce, která umožňují uživatelům zobrazit nebo transformovat obsah pocházející z hostitelské aplikace.
  • Úprava fotografií – rozšíření, které umožňuje uživatelům upravovat fotografie nebo videa v aplikaci Fotografie.
  • Zprostředkovatel dokumentů – rozšíření sloužící k umožnění přístupu jiných aplikací k dokumentům spravovaným vaší aplikací.
  • Vlastní klávesnice – rozšíření, které nahrazuje systémovou klávesnici.

Rozšíření aplikací nejsou samostatné aplikace. Poskytují rozšířené funkce aplikace (ke kterým lze přistupovat z jiných aplikací, tzv. hostitelských aplikací), které mají být efektivní a zaměřené na jeden úkol. Mají vlastní binární soubor, vlastní podpis kódu a vlastní sadu prvků, ale jsou dodávány prostřednictvím obchodu App Store jako součást binárního souboru obsahující aplikace. Jedna (obsahující) aplikace může mít více než jedno rozšíření. Jakmile uživatel nainstaluje aplikaci, která má rozšíření, budou k dispozici v celém systému iOS.

Podívejme se na příklad: Uživatel najde obrázek pomocí Safari, stiskne tlačítko sdílení a vybere rozšíření vaší aplikace pro sdílení. Safari „hovoří“ s frameworkem iOS Social, který načte a představí rozšíření. Kód rozšíření se spustí, předá data pomocí instancovaných komunikačních kanálů systému, a jakmile je úkol splněn – Safari zobrazení rozšíření zruší. Krátce poté systém proces ukončí a vaše aplikace se na obrazovce nikdy nezobrazila. Přesto dokončila funkci sdílení obrázků.

iOS je pomocí komunikace mezi procesy tím, kdo zajišťuje, aby hostitelská aplikace a rozšíření aplikace mohly spolupracovat. Vývojáři používají vysokoúrovňové rozhraní API poskytované bodem rozšíření a systémem, takže se nikdy nemusí starat o základní komunikační mechanismy.

Životní cyklus

Rozšíření aplikací mají jiný životní cyklus než aplikace iOS. Životní cyklus rozšíření zahajuje hostitelská aplikace jako reakci na akci uživatele. Poté systém instancuje rozšíření aplikace a nastaví mezi nimi komunikační kanál. Zobrazení rozšíření se zobrazí v kontextu hostitelské aplikace pomocí položek přijatých v požadavku hostitelské aplikace. Jakmile je zobrazení rozšíření zobrazeno, může s ním uživatel interagovat. V reakci na akci uživatele rozšíření dokončí požadavek hostitelské aplikace okamžitým provedením/zrušením úlohy nebo v případě potřeby zahájením procesu na pozadí k jejímu provedení. Hned poté hostitelská aplikace zruší zobrazení rozšíření a uživatel se vrátí do svého předchozího kontextu v rámci hostitelské aplikace. Výsledky provedení tohoto procesu by mohly být po jeho dokončení vráceny do hostitelské aplikace. Rozšíření se obvykle ukončí brzy poté, co dokončí požadavek přijatý od hostitelské aplikace (nebo spustí proces na pozadí k jeho provedení).

Systém otevře rozšíření akce uživatele z hostitelské aplikace, rozšíření zobrazí uživatelské rozhraní, provede nějakou práci a vrátí data hostitelské aplikaci (pokud to odpovídá typu rozšíření). Obsahující aplikace není spuštěna ani v době, kdy je spuštěno její rozšíření.

Vytvoření rozšíření aplikace – praktický příklad s použitím rozšíření Today

Rozšíření Today, nazývaná také widgety, se nacházejí v zobrazení Today oznamovacího centra. Jsou skvělým způsobem, jak uživateli prezentovat aktuální obsah (například zobrazení počasí) nebo provádět rychlé úkoly (například označování hotových věcí ve widgetu aplikace seznamu úkolů). Zde musím upozornit, že zadávání z klávesnice není podporováno.

Vytvořme rozšíření Today, které bude zobrazovat nejaktuálnější informace z naší aplikace (kód na GitHubu). Aby bylo možné tento kód spustit, ujistěte se, že jste (znovu) nakonfigurovali skupinu aplikací pro projekt (vyberte svůj vývojový tým, mějte na paměti, že název skupiny aplikací musí být jedinečný, a postupujte podle pokynů Xcode).

Vytvoření nového widgetu

Jak jsme již řekli, rozšíření aplikací nejsou samostatné aplikace. Potřebujeme obsahující aplikaci, na které budeme rozšíření aplikace stavět. Jakmile máme naši obsahující aplikaci, rozhodneme se přidat nový cíl tak, že do Xcode přejdeme na File -> New -> Target. Odtud vybereme šablonu našeho nového cíle pro přidání rozšíření Today.

V dalším kroku můžeme zvolit náš název produktu. To je název, který se bude zobrazovat v zobrazení Dnes Centra oznámení. V tomto kroku je také možnost výběru jazyka mezi Swiftem a Objective-C. Dokončením těchto kroků Xcode vytvoří šablonu Today, která poskytuje výchozí hlavičkové a implementační soubory pro hlavní třídu (pojmenovanou TodayViewController) se souborem Info.plist a souborem rozhraní (storyboard nebo soubor .xib). Soubor Info.plist ve výchozím nastavení vypadá takto:

Pokud nechcete použít storyboard poskytnutý šablonou, odstraňte klíč NSExtensionMainStoryboard a přidejte klíč NSExtensionPrincipalClass s názvem vašeho řadiče zobrazení jako hodnotou.

Vidget Today by měl:

  • zajistit, aby obsah vypadal vždy aktuálně
  • vhodně reagovat na interakce uživatele
  • dobře fungovat (widgety iOS musí rozumně využívat paměť, jinak je systém ukončí)

Sdílení dat a sdíleného kontejneru

Rozšíření aplikace i jeho obsahující aplikace mají přístup ke sdíleným datům ve svém soukromě definovaném sdíleném kontejneru. což je způsob nepřímé komunikace mezi obsahující aplikací a rozšířením.

Nemilujete, jak Apple tyto věci „zjednodušuje“ 🙂

Sdílení dat prostřednictvím NSUserDefaults je jednoduché a je to běžný případ použití. Ve výchozím nastavení rozšíření a jeho obsahující aplikace používají samostatné datové sady NSUserDefaults a nemohou vzájemně přistupovat ke svým kontejnerům. Aby se toto chování změnilo, zavedl systém iOS skupiny aplikací. Po povolení skupin aplikací v obsahující aplikaci a rozšíření použijte pro přístup ke stejnému sdílenému kontejneru místo initWithSuiteName:@"group.yourAppGroupName"].

Aktualizace widgetu

Aby bylo zajištěno, že obsah bude vždy aktuální, poskytuje rozšíření Today rozhraní API pro správu stavu widgetu a zpracování aktualizací obsahu. Systém občas pořizuje snímky zobrazení widgetu, takže když se widget stane viditelným, zobrazí se nejnovější snímek, dokud není nahrazen živou verzí zobrazení. Pro aktualizaci stavu widgetu před pořízením snímku je důležitá shoda s protokolem NCWidgetProviding. Jakmile widget přijme volání widgetPerformUpdateWithCompletionHandler:, měl by být pohled widgetu aktualizován nejnovějším obsahem a obsluha dokončení by měla být volána s jednou z následujících konstant pro popis výsledku aktualizace:

  • NCUpdateResultNewData – Nový obsah vyžaduje překreslení zobrazení
  • NCUpdateResultNoDate – Widget nevyžaduje aktualizaci
  • NCUpdateResultFailed – Během procesu aktualizace došlo k chybě

Kontrola toho, kdy je widget zobrazitelný

Pro kontrolu toho, kdy je widget zobrazen, použijte metodu setHasContent:forWidgetWithBundleIdentifier: ze třídy NCWidgetController. Tato metoda vám umožní určit stav obsahu widgetu. Lze ji zavolat z widgetu nebo z jeho obsahující aplikace (pokud je aktivní). Této metodě můžete předat příznak NO nebo YES, který určuje, zda je obsah widgetu připraven, nebo ne. Pokud obsah není připraven, systém iOS váš widget při otevření zobrazení Today nezobrazí.

Otevření obsahující aplikace z widgetu

Widget Today je jediné rozšíření, které může voláním metody openURL:completionHandler: požádat o otevření své obsahující aplikace. Aby bylo zajištěno, že se obsahující aplikace otevře způsobem, který dává smysl v kontextu aktuálního úkolu uživatele, mělo by být definováno vlastní schéma URL (které může používat jak widget, tak obsahující aplikace).

 completionHandler:nil];

UI Considerations

Při návrhu widgetu využijte třídu UIVisualEffectView, přičemž mějte na paměti, že pohledy, které mají být rozmazané/živé, musí být přidány do contentView, a ne přímo do UIVisualEffectView. Widgety (vyhovující protokolu NCWidgetProviding) by měly načítat stavy z mezipaměti v viewWillAppear:, aby odpovídaly stavu pohledu z posledního viewWillDisappear:, a pak plynule přecházet na nová data, jakmile dorazí, což není případ běžného řadiče pohledu (uživatelské rozhraní se nastavuje v viewDidLoad a animace a načítání dat zpracovává v viewWillAppear). Widgety by měly být určeny k provedení úkolu nebo k otevření obsahující aplikace jediným klepnutím. Zadávání z klávesnice není v rámci widgetu dostupné. To znamená, že by nemělo být použito žádné uživatelské rozhraní vyžadující zadávání textu.

Přidání posouvání do widgetu, a to jak vertikálního, tak horizontálního, není možné. Přesněji řečeno, přidání posuvného zobrazení je možné, ale posouvání nebude fungovat. Vodorovné gesto rolování v rolovacím zobrazení v rozšíření Dnes bude zachyceno oznamovacím centrem, což způsobí rolování z Dnes do oznamovacího centra. Vertikální rolování rolovacího zobrazení uvnitř rozšíření Dnes bude přerušeno rolováním zobrazení Dnes.

Technické poznámky

Zde upozorním na některé důležité věci, které je třeba mít na paměti při vytváření rozšíření aplikace.

Funkce společné pro všechna rozšíření

Následující položky platí pro všechna rozšíření:

  • objekt sdílené aplikace je mimo dosah:

  • Kamera a mikrofon jsou mimo omezení: Rozšíření aplikací nemohou přistupovat k fotoaparátu nebo mikrofonu v zařízení (to však neplatí pro všechny hardwarové prvky). Je to důsledek nedostupnosti některých rozhraní API. Chcete-li v rozšíření aplikace přistupovat k některým hardwarovým prvkům, musíte zkontrolovat, zda je jejich rozhraní API pro rozšíření aplikací dostupné, nebo ne (pomocí výše popsané kontroly dostupnosti rozhraní API).

  • Většina úloh na pozadí je mimo omezení:

  • Většina rozšíření aplikací nemůže provádět dlouhodobé úlohy na pozadí, s výjimkou zahájení odesílání nebo stahování, které je popsáno níže:

Nahrávání/stahování na pozadí

Jedinou úlohou, kterou lze provádět na pozadí, je nahrávání/stahování pomocí NSURLSession object.

Po zahájení úlohy nahrávání/stahování může rozšíření dokončit požadavek hostitelské aplikace a být ukončeno bez jakéhokoli vlivu na výsledek úlohy. Pokud rozšíření v době dokončení úlohy na pozadí neběží, systém spustí na pozadí obsahující aplikaci a zavolá její metodu delegáta application:handleEventsForBackgroundURLSession:completionHandler:.

Aplikace, jejíž rozšíření iniciuje úlohu na pozadí NSURLSession, musí mít nastaven sdílený kontejner, ke kterému má přístup jak obsahující aplikace, tak její rozšíření.

Ujistěte se, že jste vytvořili různé relace na pozadí pro obsahující aplikaci a každé její rozšíření (každá relace na pozadí by měla mít jedinečný identifikátor). To je důležité, protože relaci na pozadí může používat vždy jen jeden proces.

Akce vs. Sdílení

Rozdíly mezi rozšířeními Akce a Sdílení nejsou z pohledu programátora zcela jasné, protože v praxi jsou si velmi podobné. Šablona Xcode pro cíl rozšíření Share používá SLComposeServiceViewController, které poskytuje standardní uživatelské rozhraní zobrazení Compose, které můžete použít pro sdílení na sociálních sítích, ale není to nutné. Rozšíření pro sdílení může také dědit přímo z UIViewController pro zcela vlastní návrh, stejně jako může rozšíření Action dědit z SLComposeServiceViewController.

Rozdíl mezi těmito dvěma typy rozšíření je v tom, jak mají být používána. Pomocí rozšíření Action můžete vytvořit rozšíření bez vlastního uživatelského rozhraní (například rozšíření sloužící k překladu vybraného textu a vrácení překladu do hostitelské aplikace). Rozšíření Share umožňuje sdílet komentáře, fotografie, videa, zvuky, odkazy a další informace přímo z hostitelské aplikace. Rozšíření UIActivityViewController řídí jak rozšíření Action, tak Share, přičemž rozšíření Share jsou prezentována jako barevné ikony v horním řádku a rozšíření Action jsou prezentována jako černobílé ikony ve spodním řádku (obrázek 2.1).

Zakázaná API

API označená v hlavičkových souborech makrem NS_EXTENSION_UNAVAILABLE nebo podobným makrem pro nedostupnost nelze použít (např:

Pokud sdílíte kód mezi aplikací a rozšířením, musíte mít na paměti, že i odkaz na rozhraní API, které není pro dané rozšíření povoleno, povede k odmítnutí aplikace z obchodu App Store. Můžete se s tím vypořádat tak, že sdílené třídy přeformátujete do hierarchií se společným rodičem a různými podtřídami pro různé cíle.Dalším způsobem je použití preprocesoru pomocí kontrol #ifdef. Protože stále neexistuje vestavěný podmíněný cíl, musíte si vytvořit vlastní.

Dalším pěkným způsobem je vytvoření vlastního vestavěného rámce. Jen se ujistěte, že nebude obsahovat žádné API nedostupné pro rozšíření. Chcete-li nakonfigurovat rozšíření aplikace pro použití vloženého frameworku, přejděte do nastavení sestavení cíle a nastavte nastavení „Vyžadovat pouze API bezpečné pro aplikace-rozšíření“ na hodnotu Ano. Při konfiguraci projektu Xcode je třeba ve fázi sestavení Kopírovat soubory zvolit jako cíl pro vložený framework položku „Frameworks“. Pokud zvolíte cíl „SharedFrameworks“, bude vaše podání v App Store odmítnuto.

Poznámka ke zpětné kompatibilitě

Ačkoli jsou rozšíření aplikací k dispozici až od iOS 8, můžete svou obsahující aplikaci zpřístupnit i pro předchozí verze iOS.

Soulad s lidským rozhraním Apple

Při navrhování rozšíření aplikace mějte na paměti pokyny společnosti Apple pro lidské rozhraní iOS. Musíte zajistit, aby vaše rozšíření aplikace bylo univerzální bez ohledu na to, jaké zařízení vaše obsahující aplikace podporuje. Chcete-li zajistit, aby rozšíření aplikace bylo univerzální, použijte v Xcode nastavení sestavení cílové rodiny zařízení s uvedením hodnoty „iPhone/iPad“ (někdy nazývané univerzální).

Závěr

Rozšíření aplikací mají v systému iOS 8 rozhodně nejviditelnější dopad. Vzhledem k tomu, že systém iOS 8 již používá 79 % zařízení (podle měření App Store ze dne 13. dubna 2015), jsou rozšíření aplikací neuvěřitelnou funkcí, kterou by aplikace měly využít. Díky kombinaci omezení API a způsobu sdílení dat mezi rozšířeními a jejich obsahující aplikací se zdá, že se společnosti Apple podařilo vyřešit jednu z největších výtek vůči platformě, aniž by byl ohrožen její bezpečnostní model. Stále totiž neexistuje způsob, jak by aplikace třetích stran mohly mezi sebou přímo sdílet svá data. Přestože se jedná o zcela nový koncept, vypadá velmi slibně.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.