Ciao a tutti, sono Rudy Trematerra, questo è il mio primo articolo su devAPP.it ed ho scelto di parlarvi delle “Local Notification“, una delle novità più interessanti dell’iOS 4.
Le Local Notification costituiscono uno strumento molto potente per gli sviluppatori, al pari delle Push Notification, dal momento che consentono di “avvisare” l’utente con un messaggio. La differenza sostanziale tra le due sta nella modalità di ricezione delle notifiche da parte dell’iOS; infatti, le push notification per poter funzionare richiedono un servizio attivo sul sistema operativo (che consuma batteria), la connessione ad internet attiva e un server che effettua il “push” delle notifiche. Le Local notification invece, richiedono solo di “conoscere” a priori il messaggio e l’orario di visualizzazione e non necessitano di una connessione ad internet: si occuperà l’iOS di visualizzare il messaggio se la nostra applicazione non è avviata, oppure di inviare una notifica alla stessa se è aperta.
Possiamo impostare le local notification per visualizzare un messaggio, riprodurre un suono o impostare un badge all’icona dell’applicazione.
Nella mia applicazione, ad esempio, ho la necessità di “avvisare” l’utente di determinate scadenze (note a priori) e le Local Notification costituiscono lo strumento adatto per facilità d’uso sia del programmatore sia dell’utilizzatore.
Il nostro progetto
Per fare un semplice test, creeremo un’applicazione che all’avvio verifica se è stata “aperta” da una local notification ed in uscita crea una local notification.
Creiamo una “Window-based application” che chiameremo TestNotificheLocali.
Nel file “TestNotificheLocaliAppDelegate.h” aggiungiamo questi 2 metodi che utilizzeremo successivamente:
//Metodo per impostare le notifiche locali
- (void)impostaLocalNotification:(NSDate *)dataNotifica ConNome:(NSString *)nome;
//metodo per visualizzare un’ alertView
- (void) visualizzaMessaggio:(NSString*)message titolo:(NSString*)titoloFinestra;
Nel file “TestNotificheLocaliAppDelegate.m” aggiungiamo una costante che utilizzeremo per recuperare informazioni dalla local notification.
@implementation TestNotificheLocaliAppDelegate
@synthesize window;
@synthesize viewController;
#define chiaveNome @"chiaveNomeDictionary"
Impostiamo all’avvio dell’applicazione un controllo per intercettare un’eventuale apertura dell’applicazione da parte di una notifica locale.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//Richiediamo una istanza di UILocalNotification dal dictionary delle opzioni di avvio (se ci sono). Il contenuto sarà vuoto se richiamiamo direttamente l'applicazione
UILocalNotification *notifica = [launchOptions objectForKey: UIApplicationLaunchOptionsLocalNotificationKey];
//Verifichiamo se l'istanza è vuota (ad esempio abbiamo richiamato direttamente l'applicazione)
if (notifica) {
//Questo significa che l'applicazione si è avviata da un messaggio di notifica locale!
//Visualizzo il messaggio recuperando l'informazione tramite la costante utilizzata per il dictionary
[self visualizzaMessaggio:@"Programma avviato da una local notification" titolo:[notifica.userInfo objectForKey:chiaveNome]];
}
Sempre nello stesso metodo, aggiungiamo la cancellazione di tutte le notifiche locali e il richiamo del metodo per la creazione di una notifica.
//Cancelliamo tutte le notifiche locali della nostra applicazione
[[UIApplication sharedApplication] cancelAllLocalNotifications];
//Richiamiamo il metodo per la creazione della notifica
//come parametro gli passo la data attuale
[self impostaLocalNotification:[NSDate date] ConNome:@"NotificaTest"];
Il metodo accetta in ingresso la data di notifica ed il nome che visualizzeremo nell’alertView.
UILocalNotification *notifica=nil;
//Verifico che il firmware sia il 4.0
float version = [[[UIDevice currentDevice] systemVersion] floatValue];
if (version >= 4.0){
//Istanzio la variabile che mi servirà per impostare la local notification
UILocalNotification *notifica = [[UILocalNotification alloc] init];
//Imposto il fireDate che è la data ed ora di visualizzazione del messaggio
//imposto come visualizzazione 1 minuti dopo la data specificata
notifica.fireDate = [dataNotifica dateByAddingTimeInterval:(1*60)];
/*Imposto il timezone per esser certo che la data e l'ora impostate siano sempre corrette,
assegnando infatti l'oggetto timeZone, il fireDate viene regolato automaticamente
quando ci sono cambiamenti di fuso orario, di default il timeZone è "nil".
*/
notifica.timeZone = [NSTimeZone defaultTimeZone];
//Messaggio che verrà visualizzato dall'iOS se la nostra applicazione è spenta
notifica.alertBody = [NSString stringWithFormat:@"%@ - notifica locale",nome];
//Nome del pulsante per avviare la nostra applicazione
notifica.alertAction = @"Dettagli";
//Qui possiamo impostare un suono, per semplicità impostiamo il suono di default
notifica.soundName = UILocalNotificationDefaultSoundName;
//Aggiorniamo il badge dell'applicazione
notifica.applicationIconBadgeNumber = 1;
//aggiungiamo un dictionary con informazioni a piacere, in questo caso ho inserito il nome dell'evento
// per utilizzarlo successivamente richiamandolo in base alla costante
NSDictionary *infoDict = [NSDictionary dictionaryWithObjectsAndKeys:nome,chiaveNome, nil];
notifica.userInfo = infoDict;
//Impostiamo la nostra local notification
[[UIApplication sharedApplication] scheduleLocalNotification:notifica];
//Distruggiamo l'oggetto solo se istanziato
if (notifica){
[notifica release];
}
}
}
Intercettare una notifica locale quando l’applicazione è in esecuzione è semplicissimo.
//Metodo per intercettare le notifiche durante l'esecuzione dell'app
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notif {
[self visualizzaMessaggio:[notif.userInfo objectForKey:chiaveNome] titolo:@"Notifica intercettata"];
}
Questo è il metodo per visualizzare i messaggi.
- (void) visualizzaMessaggio:(NSString*)message titolo:(NSString*)titoloFinestra {
UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:titoloFinestra message:message delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil];
[alertView show];
if (alertView) {
[alertView release];
}
}
Ci sono altre proprietà che si possono impostare, ad esempio è possibile gestire la “ripetizione” del messaggio, oppure cambiare l’immagine di avvio dell’applicazione quando questa viene richiamata da una local notification.
Tutto è come sempre dettagliato nella documentazione ufficiale:
Qui c’è un ottimo esempio scritto dalla Apple:
Considerazioni finali
Come potete vedere grazie all’SDK è tutto molto semplice, la classe UILocalNotification è comunque migliorabile.
Ad esempio si potrebbe migliorare la gestione della “cancellazione” di una local notification; attualmente infatti è possibile cancellarla solo “passando” la local notification che vogliamo eliminare, richiamando il seguente metodo:
- (void)cancelLocalNotification:(UILocalNotification *)notification
Richiamando questo metodo invece cancelleremo tutte le local notification impostate dalla nostra applicazione:
- (void)cancelAllLocalNotifications
Nella mia applicazione ho la necessità di visualizzare le notifiche in base ai dati inseriti dall’utente.
Il metodo di cancellazione di una notifica locale non mi aiuta molto nelle eventuali modifiche/cancellazioni dei dati dell’utente, dal momento che, per tenerne traccia, dovrei salvarmi l’istanza creata e “legarla” al record sul database.
Inoltre sarebbe molto dispendioso in termini di sviluppo tracciare tutte le modifiche dell’utente con la possibilità di bug.
Ho scelto una strada semplice che racchiude tutta la gestione in un unico punto.
All’uscita dell’applicazione cancello le local notifications e le riscrivo in base ai dati salvati dall’utente; in tal modo sono sicuro di ricreare sempre le local notifications corrette.
Fatemi sapere cosa ne pensate di questa nuova funzionalità!









9 Responses to “T#066 – Implementiamo le Local Notification nelle nostre applicazioni iPhone”
29 Luglio 2010
Tweets that mention Implementiamo le Local Notification nelle nostre applicazioni iPhone | devAPP -- Topsy.com[…] This post was mentioned on Twitter by Rynox and iPadWorld.it, devAPP. devAPP said: Implementiamo le LOCAL NOTIFICATIONS nelle nostre applicazioni iPhone http://bit.ly/9Qptod […]
29 Luglio 2010
andreaAppCodema una cosa, ma le notifiche locali sono disponibile anche se si ha un 3G? quindi senza MT?
29 Luglio 2010
MuffaOttimo tutorial Rudy, pochi avrebbero saputo fare meglio. Continua così!
29 Luglio 2010
Rudy@andreaAppCode: Le notifiche locali funzionano anche su un 3G con firmware iOS4.
@Muffa: Grazie 😉
13 Agosto 2010
AlessioNon sono ancora molto pratico e vorrei fare una domanda: quando vado a compilare il progetto mi dà un warning, “Unused variable ‘notifica’ ” riferito alla riga:
UILocalNotification *notifica = nil;
Come faccio per far sparire questo warning?
Grazie mille! (anche per il tutorial 🙂 )
24 Agosto 2010
RudyCiao Alessio,
quel warning ti avvisa che non hai mai utilizzato quella variabile “notifica”. prova a commentare la riga o ad eliminarla e dovrebbe sparire.
//UILocalNotification *notifica = nil;
13 Settembre 2010
MarcoCiao, complimenti!
Qualche domanda…se ho intenzione di far uscire delle notifiche in base ad alcune già scelte dall’utente (preimpostate da me), ma che devono apparire random per n secondi e poi chiudersi automaticamente come posso fare? Attendo una risposta abbastanza chiara…non sono molto esperto!
27 Settembre 2010
fabrizioCiao, Grazie per il tutorial ma non capisco una cosa fondamentale per un mio progetto. Ho lo stesso problema a legare le notifiche con il mio DB. Cioè, se cancello una riga dal DB la notifica mi rimane salvata. Ma se le cancello tutte, come posso riscriverle prendendo i dati salvati nel Db??
grazie
31 Agosto 2012
giovanniSalve, è possibile fare in modo che le local notification siano disponibili anche ad applicazione chiusa? in modo da realizzare un applicazione che faccia tipo da sveglia