UILocalNotification használata

Bevezetés

Előfordulhat, hogy a mobil alkalmazásunk szeretne üzenetet küldeni a felhasználóinak, akkor is amikor az alkalmazásunk nem fut. Az üzenet egy megadott időben megjelenő párbeszéd ablakot jelent, amiben a felhasználó eldöntheti, hogy megszeretné nyitni az alkalmazást, vagy sem.

Régebben a korai iOS rendszereken, főleg szerintem a multitasking hiánya miatt csak elég bonyolultan lehetett megcsinálni az azonnali értesitést, ehhez az Apple az úgynevezett push notification service használatát tette lehetővé. Ez a programozók számára azon kívül, hogy sok munkát jelentett, még anyagi többlettel is járhatott.

Ahozz hogy a felhasználó telefonján megjelenjen egy üzenet, az üzenetünket el kellet küldeni az Apple push notification serverére, és innen küldte szét az Apple az üzenetünket a felhasználóknak. Ehhez ugye a telefonnak is online kapcsolattal kellett rendelkeznie. Megvalósításához szerver oldali scriptet kellet írni, ami egy SSL tanúsítványt állított elő, és elküldte az Apple serverére, az üzenetünk tartalmával és más egyéb információkkal együtt.

Ezért szerencsére az iOS4 megjelenésekor a multitasking bevezetésével, lehetőség nyílt a lokális értesítésekre is. Ezzel nem kell többé server oldali kódot írni, nincs szükség állandó Internet kapcsolatra, hogy megkapjunk egy üzenetet. Csak egy API használatával ütemezhetjük az üzenetünket, és az a megadott időben meg fog jeleni a telefonon.

Minta alkalmazás

A működést az előző fejezetben bemutatott egyszerű XML-s book alkalmazáson mutatom be. Ezt az alkalmazást fogom kiegészíteni, egy olyan funkcióval, ami a kölcsönzési lejárati időkre figyelmeztet a lejárat előtt egy nappal.

XML bővítése

Első lépésben kibővítem az előző fejezetben létrehozott books.xml-t egy expiration tag-el, ami egy yyyy.MM.DD. formátumú dátum lesz.

Értesítések létrehozása

Ezután, létrehoztam azt az eljárást, ami létrehozza az értesítéseket, rögtön az alkalmazás indulásakor az applicationDidFinishLaunching függvényben. Itt látható a kód:

- (void) setExpires { [[UIApplication sharedApplication] cancelAllLocalNotifications]; for (Book* book in books) { NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; // date formatter letrehozasa a string -> date konverziohoz, // ha a DateFormatter string nem egyezik az XML-ben // levo date string formatumaval akkor nil objektumot kapunk! [dateFormatter setDateFormat:@"yyyy.MM.dd"]; NSDate *dateFromString = [[NSDate alloc] init]; // \n\r karakterek torlese a datum stringbol book.expiration = [book.expiration stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]]; // datumma konvertalas dateFromString = [dateFormatter dateFromString:book.expiration]; // konverzios hiba volt? if (dateFromString == nil) { [self showMsg:[NSString stringWithFormat:@"Hiba tortent a %@ datum konvertalasakor.", book.expiration]]; continue; } // lejart a kolcsonzesi ido? if ([self isExpired:dateFromString]) { // ertesitem a felhasznalot [self showMsg:[NSString stringWithFormat:@"A %@ könyv %@-n már lejárt!", book.title, book.expiration]]; } else { // kesobb fog lejarni, letrehozom a lejarati ido - 1 nap-ra az ertesitest UILocalNotification* localNotification = [[UILocalNotification alloc] init]; dateFromString = [dateFromString dateByAddingTimeInterval:-1*24*60*60]; localNotification.fireDate = dateFromString; localNotification.alertBody = [NSString stringWithFormat:@"A %s könyv holnap lejár!", book.title]; [[UIApplication sharedApplication] scheduleLocalNotification:localNotification]; [localNotification release]; } [dateFormatter release]; } // letrehozott ertesitesek kiloggolasa [self logNotifications]; }

Az eljárásba belépve törli az alkalmazás eddig létrehozott értesítéseit, a cancelAllLocalNotifications üzenettel. Ezek frissítve lesznek, újra létrehozzom őket. Ezután indul egy ciklus a Books tömb összes elemén. Első lépésben a könyv lejárati dátum stringjét szeretnénk dátummá konvertálni. Ehhez az NSDateFormatter osztályt fogjuk felhasználni, ami képes egy stringből a megadott input string alapján egy NSDate objektumot visszaadni. Ha a DateFormatternek megadott input string nem egyezik az XML-ben levő date string formátumával, akkor nil objektumot kapunk. Amit le is ellenőriz a kód, és egy hibaüzenettel jelzi a problémát. Ha a kölcsönzési idő lejárt, akkor azt rögtön jelzem. Egyébként létrehozok egy új UILocalNotification példányt. Ez jelenti az értesítés objektumot, amit ütemezni fogunk, egy nappal a lejárati idő elé, a fireDate property-t beállitva a dátumra. Az alertBody tartalmazza az üzenetünk szövegét. És a végén az ütemezést a scheduleLocalNotification üzenettel tesszük meg.

A teljes forráskód letölthető innen.