iPad Mini kehittäjän näkökulmasta

Apple julkaisi eilen tukun uusia tuotteita, joiden mukana oli myös kokonaan uusi iOS-laite, iPad Mini. Tässä hiukan mietteitä kehittäjän näkulmasta.

iPad Mini on raudaltaan ja pikseleiltään sama kuin iPad2, eli sovellukset jotka toimivat iPad2:ssa toimivat myös iPad Minissä. Ainoat isommat erot ovat iPad Minin LTE-tuki, Siri ja luonnollisesti koko.

Internet-huhut olivat yhdessä vaiheessa sitä mieltä, että iPad Mini olisi kuvasuhteeltaan 16:9, joka olisi ollut sovelluksille huomattavasti isompi remontti, kuin iPhone 5 yhteensopivuuden tekeminen iPhone-sovelluksissa. Näin ollen kehittäjät voivat huokaista helpotuksesta, kun nykyiset sovellukset rullaavat enemmän tai vähemmän samalla tavalla kuin iPad 2:ssa.

Tervetuloa iPad Mini.

 

OpenGL ES 3.0 tulee – oletko valmis?

Aivan lyhykäisyydessään viimeaikojen uutisvirrasta poimittuna, Khronos Group on hiljattain julkaissut OpenGL ES 3.0 standardin speksin. ARM satsaa kovasti raudallaan sekä softatyökaluillaan mobiiligrafiikkaan ja toivon mukaan ensimmäiset laitteet nähdään jo pian!

Poimintoja tärkeimmistä uusista ominaisuuksista:

  • Alustariippumaton tekstuurien pakkaus on nyt osa standardia. Erittäin suuri helpotus cross-platform softan tekijöille.
  • Geometry instancing; monta kopiota samasta geometriasta (helppo esimerkki: metsän puut) voidaan nyt piirtää säästäen väylän kaistaa kun geometria tarvitsee lähettää vain kerran.
  • Occlusion queries: rautatuki artefaktien näkyvyyden selvittämiseen. Nopeuttaa ja suoraviivaistaa dramaattisesti vaikkapa lens flarejen yms. efektien toteuttamista.
  • Floating point, depth jne tekstuurit pakolliseksi osaksi speksiä
  • Ja mikä parasta, 3.0 speksi on 100% taaksepäin yhteensopiva 2.0 kanssa.

Lähteet:

 

Ehta modaalidialogi iOS:lla


Muista kehitysympäristöistä iOS-maailmaan tulevasta voi tuntua oudolta Cocoa Touchin modaalidialogien puute. Vaikkakin on mahdollista rakentaa kaiken muun päälle piirtyvä dialogi joka oletukselta (ja tämä on ohitettavissa) saa kaiken syötteen, dialogin näyttävä kutsu ei blokkaa vaan palaa välittömästi ja dialogin sulkeutuminen on otettava kiinni asynkronisella callbackilla (‘delegate’). Edes perustyökalu UIAlertView ei käyttäydy kuin muiden alustojen – vaikkapa MFC, Javascript, Symbian Series60/Series80, Java AWT/Swing, Qt, Android, GTK, jne.. – stock komponentit MessageBoxit ja InputDialogit.

Tämänkaltaista UI paradigmaa voi kuitenkin paitsi kaivata, myös tarvita; oletetaan etta ollaan rakentamassa iOS -toteutusta cross-platform sovellukseen jossa täytyy toteuttaa metodi vaikkapa seuraavasti:

std::string AskUserInput()
{
  // Semantiikka: kysy käyttäjältä syöte popup dialogilla 
  //   ja palauta annettu teksti
}

Miten tämä toteutetaan iOS:lla? Nostetaan kädet pystyyn, otetaan projektin arkkitehti Skypen päähän ja anotaan API:in muutosta joka mahdollistaisi syötteen kyselyn asynkronisen käsittelyn? Miksei, mutta jos yo. mekanismi on jo toteutettu viidelle muulle alustalle, on edessa iso muutostyö ja paljon hampaita kiristeleviä ihmisiä. Turha asynkronia näin yksinkertaisessa asiassa hankaloittaa sekä pirstaloittaa arkkitehtuuria.

Ongelman ratkaisu lähtee UI frameworkin toiminnan ymmärtämisestä. Käytännössä kaikissa moderneissa käyttöliittymäkirjastoissa on 1-N UI säiettä jotka palvelevat käyttöliittymää ns. event loopin [tapahtumakieriö?! -toim.] kautta. Event loop ottaa inputteja komponenteilta, timereilta tai vaikkapa muilta säikeiltä alustakohtaisten viestinvälitysmekanismien välityksellä ja tarjoilee niitä kiinnostuneille kuuntelijoille. Käytännössä jokaisella säikeellä on tasan yksi (tai nolla, jos kyseessä ei ole UI:ta palveleva säie) event loop, ja yleisesti mobiilikäyttöjärjestelmissä UI:ta palvelee vain yksi säie kerrallaan. Käyttöliittymä kumminkin toimii jouhevasti niin kauan kuin tätä säiettä ei varata kerralla liian pitkäksi aikaa; pitkäkestoinen laskenta täytyy joka jakaa pieniin osiin tai tehdä muissa säikeissä.

Event loopiin perustuvat järjestelmät sallivat yleensä event looppien sisäkkäisen ajamisen (nesting); tällöin vanha event loop aktivaatio pysähtyy eikä jatka ennenkuin sisempi loop aktivaatio loppuu. Tätä voidaan hyväksikäyttää asynkronian poistamiseksi; API-metodin sisällä ajetaan uusi aktivaatio, kuunnellaan asynkronista vastausta ja lopetataan aktivaatio kun vastaus on saatu. Tällöin APIa kutsuva metodi blokkaa koko suorituksen ajan. On kuitenkin erotettava tämä semaforin odottamisesta; säiehän ei ole idlena vaan suorittaa sisempää event loop aktivaatiota.

Rakennetaan esimerkkitoteutus iOS:lle. Halutaan tehda seuraavanlainen kutsu:

-(void) requestAndLogInput {
  InputDialog* dlg = [InputDialog dialog];
  [dlg showModal];
  NSLog(@"Dialog input was = %@", [dlg getInput]);
}

Aloitetaan dialogin luomisesta. Tähän käytetään normaalia Cocoa Touch boilerplatea:

+(InputDialog*) dialog {
    NSArray* nibViews = [[NSBundle mainBundle] loadNibNamed:@"InputDialog"
                                                      owner:nil
                                                    options:nil];
    InputDialog* dlg = [[[nibViews objectAtIndex:0] retain] autorelease];

    return dlg;
}

Määritellään metodi jolla dialogi näytetään modaalisti – se asettuu päällimmäiseksi ja blokkaa kunnes dialog on suljettu. iOS:lla event loop tunnetaan nimellä Run loop, ja sitä vastaavat APIt ovat NSRunLoop sekä Core Foundationin CFRunLoop*:

-(void) showModal {
    // Lisätään dialogimme keywindow'n ylimmän lapsen ylimmäksi lapseksi,
    // jolloin dialogi päätyy päällimmäiseksi view stackiin
    UIWindow* keyWindow = [[UIApplication sharedApplication] keyWindow];
    UIView* topmostView = [keyWindow.subviews objectAtIndex:0];
    [topmostView addSubview:self];

    // Sijoitetaan dialogi suunnilleen keskelle ruutua    
    CGSize s = topmostView.bounds.size;
    self.center = CGPointMake(s.width / 2, (s.height / 2) - 70);

    // Ajetaan nested run loop aktivaatio jolloin showModal kutsu blokkaa
    CFRunLoopRun();
}

Lopuksi määritellään dialogin sulkeva IBAction:

-(IBAction) okPressed {
    // Poistetaan dialogi näkyvistä
    [self removeFromSuperview];

    // Pysäytetään sisempi run loop aktivaatio; kontrolli palaa 
    // ulommalle ja showModal -kutsu palaa
    CFRunLoopStop(CFRunLoopGetCurrent());
}

Valmista! Ja koska kyseessä  ovat erilliset run loop aktivaatiot eivätkä erilliset run loopit, esimerkiksi timerit jatkavat eloaan ja autorelease pool on jaettu aktivaatioiden välillä.

 Esimerkkiprojekti Xcode 4.5 -projektina. 40kB zip

 

Jo yli puolet iPhoneista päivitetty uusimpaan iOS 6.0 käyttöjärjestelmään

iPhonen käyttäjät ovat päivittäneet puhelimiaan ahkerasti. Alle kahdessa viikossa on iOS 6.0:n osuus noussut kuuteenkymmenen prosenttiin kaikista iPhoneista ja iPadeissa vastaavat luku on 45% (lähde: BGR).

Samaan aikaan Androidilla vain hiukan yli 25% käyttäjistä on päivittänyt laitteensa 4.x.x käyttöjärjestelmiin (lähde: developer.android.com). Suurin osa käyttäjistä on jymähtänyt Gingerbreadiin, joka ilmestyi jo kaksi vuotta sitten. Syy niheään päivitykseen löytyy laitevalmistajista, jotka tarjoavat erittäin hitaasti ja huonosti päivityksiä vanhempiin laitteisiin (ja myös uudempiinkin). Apple puolestaan tukee laitteita takautuvasti huomattavasti ahkerammin ja uusin iOS 6.0 oli tarjolla heti nyt jo kolme vuotta vanhaan iPhone 3gs puhelimeen (iPad 1 tosin tipahti hiukan harmillisesti kyydistä pois).

iPhone-kehittäjille käyttäjien päivitysinto tarkoittaa sitä, että uusien käyttöjärjestelmien tuomat edut päästään hyödyntämään nopeammin. iOS 5.0 mukana tulleet storyboardit nopeuttavat kehitystyötä ja iOS 6.0 mukana viimeisimmätkin navigaatiokomponentit muuttuivat kustomoitavaksi niin, että omien viritysten tekeminen ei ole enää tarpeellista.

Nykyisellä vauhdilla jo ensi keväänä on perusteltua tähdätä iOS 6.0+ käyttöjärjestelmille suunnattujen applikaatioiden tekeminen.

Android-tablettien osuus hurjassa kasvussa.

Pew Reseach Center’s Project for Excellence in Journalism on julkaissut tutkimustilastoja Yhdysvaltojen aikuisväestön tablet-tietokoneiden käytöstä ja laitteiden osuuksista.

Hulppea 25% amerikkalaisista aikuisista omistaa tablet-tietokoneen. Luku on valtava ottaen huomioon, että ensimmäinen nykyaikainen tablet iPad ilmestyi vuonna 2010.

Applen hallitsemat tablet-markkinat ovat myös mullistuneet vuoden aikana. Siinä missä vielä vuosi sitten Applen iPadit olivat 81% koko markkinasta, on tämän vuoden luku 52% ja Androideilla 48%. Androidin markkinaosuudesta 21% menee Kindle Firellä, joka käyttää Amazonin omaa versiota Androidista. Kehittäjille tämä on sinäänsä huono uutinen, koska tämä lisää entisestään fragmentaatiota Android-alustalla (nyt kauppoja onkin 2).

Markkinaosuuksien kasvusta huolimatta iPad on edelleen tablettien webbiselaustilastoissa ykkösenä hurjalla 85% osuudella.

Yllä olevat luvut kerättiin ennen Kindle Fire HD:n ja Google Nexus 7:n kauppoihin tuloa, joten Android-laitteet ovat jo todennäköisesti ohittaneet iPadit Yhdysvalloissa. Laitteista jälkimmäinen on vihdoin myös rantautumassa Suomeenkin ja hinnaksi näyttää asettuvan 269 euroa.

Applen vastaiskua tablettien parissa odotellessa.