Windows Phonen Push Ilmoitukset

Johdanto

Vaikka Windows Phone Push Notification Services on varsin hyvin dokumentoitu erinäisissä blogeissa ja msdn.com:ssa, selkeää suomenkielistä materiaalia on vähemmän. Toivottavasti ohesta löytyvä teksti auttaa alkuun pääsemisessä!

Microsoft Push Notification Services – Toimintaidea

Windows Phone (7.5) tukee kolmenlaisia Push notifikaatiotyyppejä (ilmoituksia); toast, tile ja raw. Mikäli käyttäjä on sallinut kyseiset viestit sovelluksessa, tästä seuraa:

  • Toast-ilmoitus näkyy, vaikka sovellus on suljettuna. Tekstimuotoinen viesti näkyy ruudun yläreunassa. Koskettamalla ruudulla näkyvää toast-ilmoitusta siihen liittyvä sovellus aukeaa.
  • Tile-ilmoitus näkyy kun sovelluksen ikoni kiinnitetty aloitussivulle “pin to start”. Tile-ilmoitus voi sisältää mm. uuden grafiikan tiileen sekä numeron esimerksi indikoimaan saatujen viestien määrää.
  • Raw-ilmoitus vastaanotetaan ainoastaan kun sovellus on käynnissä.

Windows Phone-ekosysteemissä push-ilmoitukset tarvitsevat käytännössä kolme eri osapuolta toimiakseen;

  • Windows Phone-laite, jossa asennettuna sovellus, joka osaa ottaa vastaan lähetettyjä notifikaatioita (+PushClient),
  • MPNS – Microsoft Push Notification Server, jonka kautta kaikki push-ilmoitukset kulkevat Windows Phone laitteille ja
  • Application Server, joka lähettää varsinaiset notifikaatiot julkaistavaksi MPNS:n kautta.

Toiminnon asetus käyttövalmiuteen tapahtuu seuraavasti:

  • Sovellus pyytää PushClientin avulla yksilöllisen tunnuksen itselleen MPNS:ltä eli rekisteröi itsensä. Rekisteröinti tässä yhteydessä tarkoittaa sitä, että on halukas vastaanottamaan viestejä. MPNS:ltä saatu tunnus on Uri ja muotoa (esimerkki; älä käytä):
http://sn1.notify.live.net/throttledthirdparty/01.0/AAHalLoyiJgtTaiDbJoSgmFiAgAAAAADAwAAAAQUZm52OjlzOEQ2NDJDRkl5MEVFMEQ
  • Sovellus lähettää MPNS:ltä saadun Uri:n sovelluspalvelimelle, jota käyttää sovelluksen ylläpitäjä. Sovelluspalvelin pitää listaa rekisteröityneistä laitteista (eli vastaanotetuista Uri-osoitteista). Kyseisiä Uri-osoitteita käytetään yhteydenpitoon PushClientien kanssa.
  • Perustoiminnallisuus on nyt asetettu käyttövalmiiksi.

Notifikaatoiden ja datan lähetys sovelluspalvelimelta tapahtuu puolestaan seuraavasti:

  • Kun sovelluspalvelin haluaa lähettää push-notifikaation laitteelle, lähettää se HTTP POST-muotoisen pyynnön laitteen antamaan yksilölliseen Uri-osoitteeseen. Pyyntö on XML-koodattu. Uri-osoite sijaitsee MPNS:ssä.
  • MPNS:n sovelluspalvelimelta saatu viesti välitetään edelleen kohdelaitteelle.
  • Mikäli kaikkea viestintää ei halua lähettää Microsoftin palvelimen kautta ja erityisesti kun kyseessä on dataintensiivinen sovellus, voidaan push-viestiin sisällyttää uusi Uri osoittamaan suoraan sovelluspalvelimen haluamaan osoitteeseen. Päätelaitteessa oleva sovellus voi tämän jälkeen käydä erikseen hakemassa kyseisen linkitetyn tiedon itselleen.

Testataan push-ilmoituksien toimintaa käytännössä

Kokeillaan push-ilmoituksia ilman rankkaa kopioi-ja-liitä-harjoitusta…

Lataa ja pura ZIP-paketti:Recipe: Push Notification Server Side Helper for WP7
Paketti sisältää toki lähdekoodien lisäksi Word-dokumentin, joka antaa yksityiskohtaiset käyttöohjeet, mutta käydään olennaisimmat osat läpi yhdessä.

Paketissa on kaksi meitä eniten kiinnostavaa komponenttia – PushClient ja Server. PushClientin voi kääntää ja ajaa emulaattorilla WP SDK 7.1:n mukana tulleella ilmaisella Visual Studio 2010 Express for Windows Phone-työkalulla, mutta Server sovellus ei toimi sillä. Mikäli koneelta ei löydy vaihtoehtoista Visual Studiota, lataa ja asenna esimerkiksi:Visual C# 2010 Express

Aja WindowsPhone.Recipes.Push.Client- ja WindowsPhone.Recipes.Push.Server- projektit. Huomioi, että Server-projekti vaatii, että se ajetaan ‘Administrator’-moodissa, eli se suoritetaan järjestelmänvalvojana. Tämä tapahtuu vaikkapa Start-valikon kautta (Windows 7): etsi Microsoft Visual C# 2010 Express ja oikean hiirinäppäimen kautta valitse “Suorita järjestelmänvalvojana”.

Saamme kaksi uutta näkymää, kun PushClient WP emulaattorissa ja Server-ikkuna käynnistyvät. Server-ikkunan kuvaruutukaappaus on nähtävissä alhaalla vasemmalla ja PushClient-kuvakaappaus oikealla:

Server-ikkunassa ollaan juuri lähetetty toast ilmoitus puhelimeen ja kyseinen tekstiviesti näkyy vastaanottajalla oikein. Kokeile eri push-ilmoituksia! Huomaa erityisesti “Ask to pin”- ja “Counter”-alalehdykät.

Lopuksi huomioitavaa

Mikäli tehdään tuotantoon asti menevä Push Notifikaatiopalvelu:

  • Windows Phone Push-sovelluksen julkaisemiselle on tietyt ehdot, jotka pitää täyttää ennen kuin sovellus julkaistaan. Esimerkiksi käyttäjällä pitää olla mahdollisuus estää viestien kulku.
  • Sovelluksen käyttäjän olisi hyvä esitellä itsensä sovelluspalvelimen kanssa (esimerkiksi käyttäjätunnus).
  • Sovelluksen olisi hyvä kryptata MPNS:ltä saatu Uri sovelluspalvelimelle lähetettäessä.
  • OS7.0-puhelimilla on puutteensa verrattuna Mango-puhelimiin. Kannattaa miettiä mitä tehdä asian suhteen.
  • Sovelluspalvelimen saaman Uri:n käyttötavat ja tallennusturvallisuus olisi hyvä kartoittaa.

Loppusanat

Push notifikaatiot eli ilmoitukset tuovat sovelluksen kehittäjien/ylläpitäjien ja loppukäyttäjien välille suoran yhteyden. Yhteydenpidossa käytetty viestintä ei ole välttämättä kuitenkaan liian häiritsevää, koska välittömään reagointiin ei ole pakkoa (vertaa puhelinsoitto) ja tiedon ilmoitustapaa on mahdollista säätää.

On varsin todennäköistä, että push ilmoituspalvelut lisääntyvät sovelluksissa. Tiedonvälitystapa tarjoaa yrityksille loistavan tavan erottautua toisistaan. Se antaa mahdollisuuden vaikkapa edulliseen täsmämarkkinointiin pienille kohderyhmille, laajaan joukkoviestintään tai vaikkapa erittäin lyhyen aikaa voimassa oleviin erikoistarjouksiin.

Manuaalinen muistinhallinta “for dummies” iOS-alustalla osa 2

Edellisessä osassa esiteltiin tapa yksinkertaistaa muistinhallintaa tekemällä luokkamuuttujista propertyja. Tällä kertaa syvennytään hieman siihen miten ja milloin Objective-C kutsuu retain ja release metodeja objekteille. Lopuksi vielä muutama huomautus objektien säilömisestä kokoelmien sisällä.

Alla olevassa EsimerkkiYksi.h tiedostossa on esitelty muuttuja minunTeksti, josta on tehty property. Objective-C luo propertyille automaagisesti mutator-metodit eli metodit joilla muuttujan sisältöä voidaan helposti manipuloida.

EsimerkkiYksi.h

@interface EsimerkkiYksi : NSObject {
  NSString *minunTeksti;
}

@property(nonatomic,retain) NSString *minunTeksti;

-(void)esimerkkiMetodi;

@end

Alla olevassa Esimerkki.m tiedostossa on havainnollistettu miten minunTeksti objektia voidaan käsitellä gettereilla ja settereilla.

EsimerkkiYksi.m

@implementation EsimerkkiYksi
@synthesize minunTeksti;

-(void)esimerkkiMetodi {
   //Asettaa minunTeksti muuttujaan tekstin "Mun teksti!"
   self.minunTeksti = [NSString stringWithString: @"Mun teksti!"];

   //Tekee saman asian eri syntaksilla.
   [self setMinunTeksti: [NSString stringWithString: @"Mun teksti!"]];

   NSLog(@"Teksti: %@", minunTeksti);

   NSString *toinenTeksti;

   //Asettaa toinenTeksti muuttujan viittaamaan minunTeksti muuttujaan.
   toinenTeksti = self.minunTeksti;
   NSLog(@"Toinen teksti: %@", toinenTeksti);

   //Sama asia eri syntaksilla.
   toinenTeksti = [self minunTeksti];
   NSLog(@"Toinen teksti: %@", toinenTeksti);
}

@end

Ohjelmoija voi myös korvata muuttujiensa mutator-metodit haluamillaan. Yläpuolella olevaan EsimerkkiYksi luokan tapauksessa metodit voisi kirjoittaa auki seuraavanlaisesti:

-(NSString*)minunTeksti {
   return minunTeksti;
}

-(void)setMinunTeksti:(NSString*)uusiTeksti {
   //Nostaa uusiTeksti muuttujan retainCounttia yhdellä. "Ottaa vastuun objektista"
   [uusiTeksti retain];

   //Vapauttaa minunTeksti muuttujan.
   [minunTeksti release];

   //Asettaa minunTeksti muuttujan.
   minunTeksti = uusiTeksti;
}

Jos kyseiset metodit sisällytetään luokkaan niitä kutsutaan aina, kun minunTeksti muuttujaa pyydetään tai asetetaan self notaation kautta. Mahdollisia ongelmatilanteita syntyy jos setterin sisällä kutsutaan retain ja release metodeja väärissä järjestyksissä. Toinen asia mikä pitää muistaa luodessa omia mutator-metodeja on se, ettei niiden sisällä pidä koskaan käyttää self notaatiota.

Alla esimerkki tilanteesta, jossa ohjelma menee loputtomaan looppiin, koska ohjelmoija käyttää getter-metodin sisällä self notaatiota. Jos olet epävarma on parasta olla muokkaamatta propertyille luotuja mutator-metodeja.

//EI NÄIN!!!!
-(NSString*)minunTeksti {
   return self.minunTeksti;
}

Tapauksissa, joissa objekteja säilötään esimerkiksi NSArray tai NSDictionary kokoelmien sisällä on huomioitavaa, että sisään syötettäville objekteille kutsutaan automaattisesti retain metodia. Muistivuotojen välttämiseksi kokoelmiin tulee syöttää vain autoreleasettuja objekteja, ellei objektin oleteta säilyvän kokoelman tuhoutumisen jälkeen. Alla esimerkki kokoelmien käytöstä.

-(void)populoiArray {
   //EI NÄIN!!!
   NSString *testi = [[NSString alloc] initWithString: @"Testi teksti!"];
   self.testiArray = [NSArray arrayWithObject: testi];

   //testi muuttuja ei ole autoreleasettu. Muistivuoto syntyy, kun testArray tuhotaan.
}

-(void)populoiToinenArray {
   //NÄIN
   NSString *testi = [NSString stringWithString: @"Testi teksti!"];
   self.testiArray = [NSArray arrayWithObject: testi];

   //testi muuttuja on autoreleasettu, testiArray ottaa sen haltuun ja vapauttaa sen, kun testArray tuhotaan.
}

Mitä voimme oppia Facebook-sovelluksen kotinäkymän kehityksestä?

Applen tarjoama standardiratkaisu iPhone-sovelluksen osiosta toiseen liikkumiseen on enimmillään viisipaikkainen tab bar. Jos on tarvetta useammalle osiolle, viimeiseksi valinnaksi voidaan laittaa kolme pistettä, ja sijoittaa tämän taakse listamuodossa lisäkohteita.

Apple tulee omissa sovelluksissaan toimeen tällä ratkaisulla, mutta usein on tarvetta toteuttaa navigaatio jotenkin muuten. Tärkeitä kohteita saattaa olla enemmän kuin viisi tai näytön pinta-ala haluttaisiin tehokkaammin käyttöön, eikä näytön alalaitaa raaskita varata navigointipalkille.

Facebookin iPhone-sovellus käytti alkuaikoinaan myös tätä ratkaisua. Ohessa kuvakaappaus versiosta 2.0 (cnet.com).

Kuvassa pistää erityisesti silmään vaikeakäyttöinen vieritettävä navigointipalkki välilehtirakenteen alapuolella. Muistan, ettei sen kanssa ollut mukava näpertää. Tab bar, välilehdet, vieritettävä palkki – on siinä hierarkiaa kerrakseen! Ei ihme, että Facebook päätti panna navigaation uusiksi sovelluksen 3.0-versiossa.

Versiossa 3.0 esiteltiin sittemmin varsin laajasti käytetty kotinäkymäpatterni, jossa päänavigaatio on koko ruudun kokoinen. Skaalautuminen hoidetaan samaan tapaan kuin iPhonen kotinäytöllä, näyttö kerrallaan vaakasuunnassa vierittämällä. (kuva Ars Technica)

Etuna on, että kohteita mahtuu näkyviin enemmän kuin tab bariin ja näkymästä saadaan visuaalisempi. Valikko ei myöskään haaskaa tilaa muilta näkymiltä. Haittapuolena on, että valikko täytyy avata erillisellä painalluksella.

Päädyimme vastaavaan ratkaisuun viime kesänä myös Taloussanomien iPhone-version kanssa. Ensin toteutetussa iPad-versiossa tärkeimmät osiot olivat mahtuneet näkyviin vaakasuuntaiseen palkkiin, mutta puhelimen ruudulla olisi tullut ahdasta emmekä halunneet tuoda ylimääräistä palkkia pystysuuntaista tilaa viemään, joten toteutimme kotinäkymäratkaisun.

Facebookiin tapaan sovellus aukeaa ensisijaisesti tärkeimpään uutisnäkymään, ja kotinäkymään pääsee erikseen painamalla. Käytimme painikkeen symbolina Facebookista poiketen talon kuvaa, sillä Facebookin käyttämä kuva toi liikaa mieleen list/grid-painikkeen.

Pian saimme huomata, että ratkaisu oli juuri mennyt muodista. Facebookin nykyinen versio toi mukanaan uuden version kotinäkymästä. Se ei enää olekaan erillinen koko ruudun näkymä, vaan näytön reunasta aukeava osittain valitun näkymän alle peittoon jäävä lista. Vierityssuunnaksi on valittu jälleen Applen standardin more-näkymän tapaan pystysuunta.

Jos vanha kotinappi näytti grid-valinnalta, uusi näyttää vastaavasti list-napilta…

Raa’asti painallusten määrällä analysoiden tämä lähestymistapa ei ole sen tehokkaampi kuin aiempi koko ruudun kotinäkymä. Yhtä lailla se vaatii yhden painalluksen aueatakseen ja samaan tapaan se estää nykyisen näkymän käytön valikon ollessa auki. Henkinen etäisyys osittain nykyisen näytön takaa aukeavaan valikkoon sen sijaan tuntuu lyhyemmältä.

Valikon vaikutelma ei ole yhtä visuaalinen kuin koko ruudun kotinäkymän ja mikä yllättävintä, listaan ei mahdu sen enempää kohteitatakaan. Aiempaan kotinäkymään mahtuu hakuluukku ja yhdeksän kohdetta. Uudessa listassa on hakuluukun lisäksi vain kahdeksan kohdetta.

Niin tai näin, uusi patterni on jo osoittautunut suosituksi. Google on ottanut sen käyttöönsa iPhonen Gmail-sovelluksessa oleellisella parannuksella: valikon saa näkyviin ja piiloon valikkonapin lisäksi sormella pyyhkäisemällä.

Viimeiseen asti hiotusta käyttöliittymästään tunnettu oman elämänsä facebook Path on toteuttanut kenties hienoimman version tästä lähestymistavasta. Valikko aukeaa Gmailin tapaan pyyhkäisyeleellä, mutta toimii huomattavasti pehmeämmin joustopomppuineen kaikkineen. Vastaavasti osiosta toiseen siirryttäessä se animoituu hetkeksi pois näkyvistä ja palaa takasin niin, että näkymä on jo valmiiksi piirretty.