A Tutorial on iOS 8 App Extensions

Vähän oli yrittänyt aiemmin (katso tätä), mutta Apple määritteli ensimmäisen iPhonen myötä, miltä älypuhelimen ja mobiilikäyttöjärjestelmän pitäisi näyttää. Apple teki uskomattoman läpimurron laitteistossa ja käyttäjäkokemuksessa. Unohdamme kuitenkin usein, että se asetti myös standardit sille, miten mobiilikäyttöjärjestelmän pitäisi toimia ja miten älypuhelinsovellukset pitäisi tehdä.

Sovellusten välille rakennettiin betoniseinät, jotka tekivät niistä täysin eristettyjä ja toisistaan tietämättömiä, mikä oli paras tapa pitää ne turvallisina ja suojata tietoja. iOS valvoi tarkasti kaikkia toimintoja, ja oli vain kourallinen toimintoja, joita sovellus olisi voinut tehdä sen soveltamisalan ulkopuolella.

”Pidättäytyminen on paras suoja!” – mutta missä siinä on hauskuus?

Siltä kesti jonkin aikaa; liian kauan, jos minulta kysytään, mutta iOS 8:n myötä Apple päätti pitää hauskaa. iOS 8 otti käyttöön uuden käsitteen nimeltä App Extensions. Tämä uusi ominaisuus ei murtanut sovellusten välisiä muureja, mutta se avasi muutamia ovia tarjoten lempeän mutta konkreettisen kontaktin joidenkin sovellusten välillä. Viimeisin päivitys antoi iOS-kehittäjille mahdollisuuden muokata iOS-ekosysteemiä, ja odotamme innolla, että tämäkin polku aukeaa.

Mitä iOS 8 App Extensions ovat ja miten ne toimivat?

Yksinkertaisesti sanottuna iOS 8 App Extensions tarjoaa uuden tavan olla vuorovaikutuksessa sovelluksen kanssa ilman, että sitä käynnistetään tai näytetään näytöllä.

Odotetusti Apple piti huolen siitä, että he pysyvät kaikessa kärjessä, joten on vain kourallinen uusia sisäänpääsypisteitä, joita sovelluksesi voi tarjota:

  • Tänään (kutsutaan myös widgetiksi) – Ilmoituskeskuksen Tänään-näkymässä näkyvä laajennus näyttää lyhyitä tietoja ja mahdollistaa nopeiden tehtävien suorittamisen.
  • Jaa – laajennus, jonka avulla sovelluksesi voi jakaa sisältöä käyttäjien kanssa sosiaalisissa verkostoissa ja muissa jakopalveluissa.
  • Toiminto – laajennus, jonka avulla voit luoda mukautettuja toimintopainikkeita Toiminto-taulukkoon, jotta käyttäjät voivat tarkastella tai muuntaa isäntäsovelluksesta peräisin olevaa sisältöä.
  • Valokuvien muokkaus – laajennus, jonka avulla käyttäjät voivat muokata valokuvaa tai videota Valokuvat-sovelluksessa.
  • Asiakirjojen tarjoaja – laajennus, jonka avulla muut sovellukset voivat käyttää sovelluksesi hallinnoimia asiakirjoja.
  • Mukautettu näppäimistö – laajennus, joka korvaa järjestelmän näppäimistön.

Sovelluslaajennukset eivät ole itsenäisiä sovelluksia. Ne tarjoavat sovelluksen laajennettuja toimintoja (joita voidaan käyttää muista sovelluksista, joita kutsutaan isäntäsovelluksiksi), joiden on tarkoitus olla tehokkaita ja keskittyä yhteen tehtävään. Niillä on oma binääri, oma koodisignatuuri ja oma joukko elementtejä, mutta ne toimitetaan App Storen kautta osana sisältävän sovelluksen binääriä. Yhdellä (sisältävällä) sovelluksella voi olla useampi kuin yksi laajennus. Kun käyttäjä asentaa sovelluksen, jolla on laajennuksia, ne ovat käytettävissä koko iOS:ssä.

Katsotaanpa esimerkkiä: Käyttäjä löytää kuvan Safarilla, painaa jakopainiketta ja valitsee sovelluksesi laajennuksen jakamista varten. Safari ”puhuu” iOS Social -kehyksen kanssa, joka lataa ja esittää laajennuksen. Laajennuksen koodi suoritetaan, se välittää tietoja käyttäen järjestelmän instansoituja viestintäkanavia, ja kun tehtävä on suoritettu – Safari purkaa laajennuksen näkymän. Pian tämän jälkeen järjestelmä lopettaa prosessin, eikä sovellustasi koskaan näytetty näytöllä. Silti se suoritti kuvanjakotoiminnon.

iOS on prosessien välisen viestinnän avulla vastuussa siitä, että isäntäsovellus ja sovelluslaajennus voivat toimia yhdessä. Kehittäjät käyttävät laajennuspisteen ja järjestelmän tarjoamia korkean tason API-rajapintoja, joten heidän ei tarvitse koskaan huolehtia taustalla olevista viestintämekanismeista.

Elinkaari

Sovelluslaajennuksilla on erilainen elinkaari kuin iOS-sovelluksilla. Isäntäsovellus käynnistää laajennuksen elinkaaren vastauksena käyttäjän toimintaan. Sen jälkeen järjestelmä instanttisoi sovelluslaajennuksen ja perustaa niiden välisen viestintäkanavan. Laajennuksen näkymä näytetään isäntäsovelluksen kontekstissa käyttäen isäntäsovelluksen pyynnössä vastaanotettuja kohteita. Kun laajennuksen näkymä on näytetty, käyttäjä voi olla vuorovaikutuksessa sen kanssa. Vastauksena käyttäjän toimintaan laajennus suorittaa isäntäsovelluksen pyynnön loppuun suorittamalla/peruuttamalla tehtävän välittömästi tai tarvittaessa käynnistämällä taustaprosessin sen suorittamiseksi. Heti tämän jälkeen isäntäsovellus purkaa laajennuksen näkymän ja käyttäjä palaa aiempaan kontekstiinsa isäntäsovelluksessa. Tämän prosessin suorittamisen tulokset voitaisiin palauttaa isäntäsovellukseen prosessin päätyttyä. Laajennus lopetetaan yleensä pian sen jälkeen, kun se on suorittanut isäntäsovellukselta saadun pyynnön (tai käynnistänyt taustaprosessin sen suorittamiseksi).

Järjestelmä avaa käyttäjän toiminnon laajennuksen isäntäsovelluksesta, laajennus näyttää käyttöliittymän, suorittaa jonkin verran työtä ja palauttaa tietoja isäntäsovellukselle (jos se sopii laajennuksen tyyppiin). Sisältävä sovellus ei ole edes käynnissä, kun sen laajennus on käynnissä.

Sovelluslaajennuksen luominen – käytännön esimerkki Today-laajennuksen käyttäminen

The Today-laajennukset, joita kutsutaan myös widgetiksi, sijaitsevat Ilmoituskeskuksen Today-näkymässä. Ne ovat erinomainen tapa esittää käyttäjälle ajantasaista sisältöä (kuten sääolosuhteiden näyttäminen) tai suorittaa nopeita tehtäviä (kuten tehtyjen asioiden merkitseminen tehtävälistasovelluksen widgetissä). Täytyy huomauttaa tässä yhteydessä, että näppäimistösyöttöä ei tueta.

Luotaan Today-laajennus, joka näyttää sovelluksemme ajantasaisimmat tiedot (koodi GitHubissa). Tämän koodin suorittamiseksi varmista, että olet (uudelleen)määrittänyt projektin sovellusryhmän (valitse kehitysryhmäsi, muista, että sovellusryhmän nimen on oltava yksilöllinen, ja noudata Xcoden ohjeita).

Uuden widgetin luominen

Kuten sanoimme jo aiemmin, sovelluksen laajennukset eivät ole itsenäisiä sovelluksia. Tarvitsemme sisältävän sovelluksen, jonka päälle rakennamme sovelluslaajennuksen. Kun meillä on sisältävä sovellus, päätämme lisätä uuden kohteen navigoimalla Xcodessa kohtaan File -> New -> Target. Täältä valitsemme mallin uudelle kohteellemme lisätäksemme Today Extension.

Seuraavassa vaiheessa voimme valita tuotteen nimen. Tämä on nimi, joka näkyy Ilmoituskeskuksen Today-näkymässä. Tässä vaiheessa on myös mahdollisuus valita kieli Swiftin ja Objective-C:n välillä. Kun nämä vaiheet on suoritettu loppuun, Xcode luo Today-mallin, joka tarjoaa oletusarvoiset otsikko- ja toteutustiedostot pääluokalle (nimeltään TodayViewController) Info.plist-tiedostolla ja rajapintatiedostolla (storyboard- tai .xib-tiedosto). Oletusarvoisesti Info.plist-tiedosto näyttää tältä:

Jos et halua käyttää mallin tarjoamaa storyboardia, poista NSExtensionMainStoryboard-avain ja lisää NSExtensionPrincipalClass-avain, jonka arvona on näkymäohjaimesi nimi.

Tänään widgetin pitäisi:

  • varmistaa, että sisältö näyttää aina ajantasaiselta
  • reagoida asianmukaisesti käyttäjän vuorovaikutukseen
  • suorituskykyinen (iOS-widgettien on käytettävä muistia viisaasti, tai järjestelmä lopettaa ne)

Datan jakaminen ja jaettu kontti

Sovelluslaajennuksella ja sitä sisältävällä sovelluksella on molemmilla pääsy jaettuun dataan, joka on jaettu jaettuun konttiinsa, joka on määritetty yksityisesti. mikä on tapa epäsuoraan viestintään sisältävän sovelluksen ja laajennuksen välillä.

Eikö olekin ihanaa, miten Apple tekee näistä asioista niin ”yksinkertaisia” 🙂

Datan jakaminen NSUserDefaults kautta on yksinkertaista ja yleinen käyttötapaus. Oletusarvoisesti laajennus ja sen sisältävä sovellus käyttävät erillisiä NSUserDefaults-tietoaineistoja, eivätkä voi käyttää toistensa kontteja. Tämän käyttäytymisen muuttamiseksi iOS otti käyttöön App Groupit. Kun olet ottanut sovellusryhmät käyttöön sisältävässä sovelluksessa ja laajennuksessa, käytä :n sijasta initWithSuiteName:@"group.yourAppGroupName"]:a samaan jaettuun konttiin pääsemiseksi.

Widgetin päivittäminen

Voidaksesi varmistaa, että sisältö on aina ajan tasalla, Today-laajennus tarjoaa sovellusrajapinnan widgetin tilan hallintaa ja sisällön päivitysten käsittelyä varten. Järjestelmä ottaa ajoittain tilannekuvia widgetin näkymästä, joten kun widget tulee näkyviin, viimeisin tilannekuva näytetään, kunnes se korvataan näkymän live-versiolla. NCWidgetProviding-protokollan noudattaminen on tärkeää widgetin tilan päivittämiseksi ennen tilannekuvan ottamista. Kun widget vastaanottaa widgetPerformUpdateWithCompletionHandler:-kutsun, widgetin näkymä on päivitettävä uusimmalla sisällöllä ja loppuunsaattamisen käsittelijää on kutsuttava jollakin seuraavista vakioista kuvaamaan päivityksen tulosta:

  • NCUpdateResultNewData – Uusi sisältö vaatii näkymän uudelleen piirtämistä
  • NCUpdateResultNoDate – Widget ei vaadi päivitystä
  • NCUpdateResultFailed – Päivitystapahtuman aikana tapahtui virhe

Widgetin katselukelpoisuuden hallitseminen

Vedgetin katselukelpoisuuden hallitseminen

Vedgettien näyttämisaikojen hallitseminen – luokassa tapahtuu luokassa. Tämän metodin avulla voit määrittää widgetin sisällön tilan. Sitä voidaan kutsua widgetistä tai sen sisältävästä sovelluksesta (jos se on aktiivinen). Voit välittää tähän metodiin NO– tai YES-lipun, joka määrittää, onko widgetin sisältö valmis vai ei. Jos sisältö ei ole valmis, iOS ei näytä widgettiäsi, kun Today-näkymä avataan.

Sisältävän sovelluksen avaaminen widgetistä

Today-widget on ainoa laajennus, joka voi pyytää sisältävän sovelluksensa avaamista kutsumalla openURL:completionHandler:-metodia. Sen varmistamiseksi, että sisältävä sovellus aukeaa tavalla, joka on järkevä käyttäjän nykyisen tehtävän kontekstissa, on määriteltävä mukautettu URL-skeema (jota sekä widget että sisältävä sovellus voivat käyttää).

 completionHandler:nil];

UI:n näkökohtia

Suunniteltaessa widgettiä kannattaa hyödyntää UIVisualEffectView-luokkaa pitäen mielessä, että näkymät, jotka halutaan hämärtää/vibroida, on lisättävä contentView-luokkaan, eikä suoraan UIVisualEffectView-luokkaan. Widgettien (jotka ovat NCWidgetProviding-protokollan mukaisia) pitäisi ladata välimuistiin tallennetut tilat viewWillAppear::ssä, jotta ne vastaisivat näkymän tilaa edellisestä viewWillDisappear::stä ja siirtyisivät sitten sujuvasti uusiin tietoihin, kun ne saapuvat, mitä ei tapahdu tavallisessa näkymäohjaimessa (käyttöliittymä asetetaan viewDidLoad:ssä ja se käsittelee animaatioita ja tietojen lataamista viewWillAppear:ssa). Widgetit pitäisi suunnitella tehtävän suorittamiseen tai sisältävän sovelluksen avaamiseen yhdellä napautuksella. Näppäimistön syöttö ei ole käytettävissä widgetin sisällä. Tämä tarkoittaa, että mitään tekstinsyöttöä vaativaa käyttöliittymää ei tulisi käyttää.

Vierityksen lisääminen widgettiin, sekä pysty- että vaakasuunnassa, ei ole mahdollista. Tai tarkemmin sanottuna vieritysnäkymän lisääminen on mahdollista, mutta vieritys ei toimi. Tänään-laajennuksen vieritysnäkymässä oleva vaakasuora vieritysliike siepataan ilmoituskeskukseen, mikä aiheuttaa vierityksen Tänäänstä ilmoituskeskukseen. Pystysuora vieritys vieritysnäkymässä Today-laajennuksen sisällä keskeytyy vierittämällä Today-näkymää.

Teknisiä huomautuksia

Tässä huomautan muutamista tärkeistä asioista, jotka on syytä pitää mielessä App-laajennusta luotaessa.

Ominaisuudet, jotka ovat yhteisiä kaikille laajennuksille

Seuraavat seikat pitävät paikkansa kaikissa laajennuksissa:

  • Jako-applikaatio-objekti on poissa käytöstä: Sovelluslaajennukset eivät voi käyttää sharedApplication-objektia tai mitään siihen liittyviä metodeja.

  • Kamera ja mikrofoni ovat kiellettyjä: Sovelluslaajennukset eivät voi käyttää laitteen kameraa tai mikrofonia (mutta tämä ei koske kaikkia laitteistoelementtejä). Tämä johtuu siitä, että jotkin API:t eivät ole käytettävissä. Jos haluat käyttää joitakin laitteistoelementtejä sovelluslaajennuksessa, sinun on tarkistettava, onko sen API käytettävissä sovelluslaajennuksille vai ei (edellä kuvatulla API:n saatavuuden tarkistamisella).

  • Useimmat taustatehtävät ovat poissa käytöstä: Sovelluslaajennukset eivät voi suorittaa pitkäkestoisia taustatehtäviä, lukuun ottamatta latausten tai latausten aloittamista, jota käsitellään jäljempänä.

  • AirDrop on kielletty: Sovelluslaajennukset eivät voi vastaanottaa (mutta voivat lähettää) tietoja AirDropin avulla.

Lataaminen/lataaminen taustalla

Yksi tehtävä, joka voidaan suorittaa taustalla, on lataaminen/lataaminen NSURLSession object:n avulla.

Kun lataus-/lataustehtävä on aloitettu, laajennus voi suorittaa isäntäsovelluksen pyynnön loppuun ja sen jälkeen lopettaa sen ilman, että sillä on vaikutusta tehtävän tulokseen. Jos laajennus ei ole käynnissä taustatehtävän päättyessä, järjestelmä käynnistää sisältävän sovelluksen taustalla ja sovelluksen delegointimenetelmää application:handleEventsForBackgroundURLSession:completionHandler: kutsutaan.

Sovelluksella, jonka laajennus käynnistää NSURLSession-taustatehtävän, on oltava jaettu kontti, jota sekä sisältävä sovellus että sen laajennus voivat käyttää.

Varmista, että sisältävälle sovellukselle ja kullekin sen sovelluksen laajennukselle on luotu erilaiset tausta-istunnot (kullakin tausta-istunnolla on oltava yksilöllinen tunniste). Tämä on tärkeää, koska vain yksi prosessi voi käyttää taustaistuntoa kerrallaan.

Action vs. Share

Action- ja Share-laajennusten väliset erot eivät ole koodaajan näkökulmasta täysin selkeitä, koska käytännössä ne ovat hyvin samanlaisia. Xcoden malli Share-laajennuksen kohdetta varten käyttää SLComposeServiceViewController, joka tarjoaa vakiomuotoisen compose-näkymän käyttöliittymän, jota voit käyttää sosiaaliseen jakamiseen, mutta sitä ei tarvita. Jaa-laajennus voi myös periytyä suoraan UIViewControllerista täysin mukautettua suunnittelua varten, samalla tavalla kuin Action-laajennus voi periytyä SLComposeServiceViewController:stä.

Eroja näiden kahden tyyppisten laajennusten välillä on siinä, miten niitä on tarkoitus käyttää. Action-laajennuksen avulla voit rakentaa laajennuksen, jolla ei ole omaa käyttöliittymää (esimerkiksi laajennuksen, jota käytetään valitun tekstin kääntämiseen ja käännöksen palauttamiseen isäntäsovellukseen). Share-laajennuksen avulla voit jakaa kommentteja, valokuvia, videoita, ääntä, linkkejä ja muuta suoraan isäntäsovelluksesta. UIActivityViewController ohjaa sekä Toiminta- että Jaa-laajennuksia, jolloin Jaa-laajennukset esitetään värillisinä kuvakkeina ylärivillä ja Toiminta-laajennukset yksivärisinä kuvakkeina alarivillä (Kuva 2.1).

Tokielletut API:t

API:itä, jotka on merkitty otsikkotiedostoissa NS_EXTENSION_UNAVAILABLE-makrolla tai vastaavalla makrolla saavuttamattomuutta osoittavalla makrolla, ei voi käyttää (esim: HealthKit- ja EventKit-käyttöliittymäkehykset iOS 8:ssa eivät ole käytettävissä missään sovelluslaajennuksessa).

Jos jaat koodia sovelluksen ja laajennuksen välillä, sinun on muistettava, että jopa viittaaminen API:hin, joka ei ole sallittu sovelluslaajennuksessa, johtaa sovelluksesi hylkäämiseen App Storesta. Voit käsitellä tätä käsittelemällä jaetut luokat uudelleen hierarkioiksi, joilla on yhteinen vanhempi ja eri alaluokat eri kohteille.Toinen tapa on käyttää esikäsittelijän #ifdef-tarkistuksia. Koska vieläkään ei ole sisäänrakennettua kohdeehtoa, sinun on luotava oma.

Toinen mukava tapa on luoda oma sulautettu kehys. Varmista vain, että se ei sisällä mitään API:ta, joka ei ole saatavilla laajennuksille. Jos haluat määrittää sovelluksen laajennuksen käyttämään sulautettua kehystä, siirry kohteen build-asetuksiin ja aseta ”Require Only App-Extension-Safe API” -asetuksen arvoksi Kyllä. Xcode-projektia määritettäessä Kopioi tiedostot -rakentamisvaiheessa ”Frameworks” on valittava sulautetun kehyksen kohteeksi. Jos valitset määränpään ”SharedFrameworks”, App Store hylkää lähetyksen.

Huomautus taaksepäin yhteensopivuudesta

Vaikka sovelluslaajennukset ovat olleet käytettävissä vasta iOS 8:sta lähtien, voit tehdä sisältävästä sovelluksestasi saatavan aiemmille iOS-versioille.

Applen käyttöliittymän yhteensopivuus

Osaa pitää mielessäsi Applen iOS:n iOS-käyttöliittymäsuositukset sovelluslaajennuksen suunnittelussa. Sinun on varmistettava, että sovelluksen laajennuksesi on universaali riippumatta siitä, mitä laitetta sisältävä sovelluksesi tukee. Varmistaaksesi, että sovelluksen laajennus on universaali, käytä Xcoden kohdennetun laiteperheen rakentamisasetusta, jossa määritetään arvo ”iPhone/iPad” (joskus kutsutaan universaaliksi).

Johtopäätös

Sovelluslaajennuksilla on ehdottomasti näkyvin vaikutus iOS 8:ssa. Koska 79 % laitteista käyttää jo iOS 8:aa (App Storen mittausten mukaan 13. huhtikuuta 2015), sovelluslaajennukset ovat uskomattomia ominaisuuksia, joita sovellusten tulisi hyödyntää. Yhdistämällä API:n rajoitukset ja tavan jakaa tietoja laajennusten ja niitä sisältävän sovelluksen välillä näyttää siltä, että Apple onnistui vastaamaan yhteen alustan suurimmista valituksista tinkimättä sen turvallisuusmallista. Kolmannen osapuolen sovellukset eivät edelleenkään voi jakaa tietojaan suoraan keskenään. Vaikka tämä on hyvin uusi konsepti, se näyttää erittäin lupaavalta.

Vastaa

Sähköpostiosoitettasi ei julkaista.