{"id":4202,"date":"2010-07-29T09:47:18","date_gmt":"2010-07-29T07:47:18","guid":{"rendered":"http:\/\/www.devapp.it\/wordpress\/?p=4202"},"modified":"2010-07-29T09:47:18","modified_gmt":"2010-07-29T07:47:18","slug":"t066-implementiamo-le-local-notification-nelle-nostre-applicazioni-iphone","status":"publish","type":"post","link":"https:\/\/www.devapp.it\/wordpress\/t066-implementiamo-le-local-notification-nelle-nostre-applicazioni-iphone\/","title":{"rendered":"T#066 &#8211; Implementiamo le Local Notification nelle nostre applicazioni iPhone"},"content":{"rendered":"<p><a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/07\/iphone-os4-local-notification.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/07\/iphone-os4-local-notification.png\" alt=\"iphone os4 local notification\" title=\"iphone-os4-local-notification\" width=\"150\" height=\"103\" class=\"alignleft size-full wp-image-4206\" \/><\/a> Ciao a tutti, sono Rudy Trematerra, questo \u00e8 il mio primo articolo su devAPP.it ed ho scelto di parlarvi delle &#8220;<strong>Local Notification<\/strong>&#8220;, una delle novit\u00e0 pi\u00f9 interessanti dell&#8217;iOS 4.<br \/>\nLe Local Notification costituiscono uno strumento molto potente per gli sviluppatori, al pari delle <em>Push Notification<\/em>, dal momento che consentono di &#8220;avvisare&#8221; l\u2019utente con un messaggio. La differenza sostanziale tra le due sta nella modalit\u00e0 di ricezione delle notifiche da parte dell\u2019iOS; 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 \u201cpush\u201d delle notifiche. Le Local notification invece, richiedono solo di &#8220;conoscere&#8221; a priori il messaggio e l&#8217;orario di visualizzazione e non necessitano di una connessione ad internet: si occuper\u00e0 l&#8217;iOS di visualizzare il messaggio se la nostra applicazione non \u00e8 avviata, oppure di inviare una notifica alla stessa se \u00e8 aperta.<!--more--><\/p>\n<p>Possiamo impostare le local notification per visualizzare un messaggio, riprodurre un suono o impostare un badge all&#8217;icona dell&#8217;applicazione.<\/p>\n<p>Nella mia applicazione, ad esempio, ho la necessit\u00e0 di &#8220;avvisare&#8221; l&#8217;utente di determinate scadenze (note a priori) e le <em>Local Notification<\/em> costituiscono lo strumento adatto per facilit\u00e0 d&#8217;uso sia del programmatore sia dell&#8217;utilizzatore.<\/p>\n<h4>Il nostro progetto<\/h4>\n<p>Per fare un semplice test, creeremo un&#8217;applicazione che all&#8217;avvio verifica se \u00e8 stata &#8220;aperta&#8221; da una local notification ed in uscita crea una local notification.<\/p>\n<p>Creiamo una &#8220;Window-based application&#8221; che chiameremo TestNotificheLocali.<\/p>\n<p>Nel file &#8220;TestNotificheLocaliAppDelegate.h&#8221; aggiungiamo questi 2 metodi che utilizzeremo successivamente:<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n\/\/Metodo per impostare le notifiche locali\r\n- (void)impostaLocalNotification:(NSDate *)dataNotifica ConNome:(NSString *)nome;\r\n\/\/metodo per visualizzare un\u2019 alertView\r\n- (void) visualizzaMessaggio:(NSString*)message titolo:(NSString*)titoloFinestra;\r\n<\/pre>\n<p>Nel file &#8220;TestNotificheLocaliAppDelegate.m&#8221; aggiungiamo una costante che utilizzeremo per recuperare informazioni dalla local notification. <\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n@implementation TestNotificheLocaliAppDelegate\r\n\r\n@synthesize window;\r\n@synthesize viewController;\r\n\r\n#define chiaveNome @\"chiaveNomeDictionary\"\r\n<\/pre>\n<p>Impostiamo all\u2019avvio dell\u2019applicazione un controllo per intercettare un\u2019eventuale apertura dell\u2019applicazione da parte di una notifica locale.<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {    \r\n\r\n\t\/\/Richiediamo una istanza di UILocalNotification dal dictionary delle opzioni di avvio (se ci sono). Il contenuto sar\u00e0 vuoto se richiamiamo direttamente l'applicazione\r\n\tUILocalNotification *notifica = [launchOptions objectForKey: UIApplicationLaunchOptionsLocalNotificationKey]; \r\n\r\n\t\/\/Verifichiamo se l'istanza \u00e8 vuota (ad esempio abbiamo richiamato direttamente l'applicazione)\r\n\tif (notifica) {\r\n\t\t\/\/Questo significa che l'applicazione si \u00e8 avviata da un messaggio di notifica locale!\r\n\r\n\t\t\/\/Visualizzo il messaggio recuperando l'informazione tramite la costante utilizzata per il dictionary\r\n\t\t[self visualizzaMessaggio:@\"Programma avviato da una local notification\" titolo:[notifica.userInfo objectForKey:chiaveNome]];\r\n\t}\r\n<\/pre>\n<p>Sempre nello stesso metodo, aggiungiamo la cancellazione di tutte le notifiche locali e il richiamo del metodo per la creazione di una notifica.<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n\t\/\/Cancelliamo tutte le notifiche locali della nostra applicazione\r\n\t[[UIApplication sharedApplication] cancelAllLocalNotifications];\r\n\t\r\n\t\/\/Richiamiamo il metodo per la creazione della notifica\r\n\t\/\/come parametro gli passo la data attuale\r\n\t[self impostaLocalNotification:[NSDate date] ConNome:@\"NotificaTest\"];\r\n<\/pre>\n<p>Il metodo accetta in ingresso la data di notifica ed il nome che visualizzeremo nell\u2019alertView.<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n\tUILocalNotification *notifica=nil;\r\n\t\r\n\t\/\/Verifico che il firmware sia il 4.0\r\n\tfloat version = [[[UIDevice currentDevice] systemVersion] floatValue];\r\n\tif (version >= 4.0){\r\n\t\t\r\n\t\t\/\/Istanzio la variabile che mi servir\u00e0 per impostare la local notification\r\n\t\tUILocalNotification *notifica = [[UILocalNotification alloc] init];\r\n\r\n\t\t\r\n\t\t\/\/Imposto il fireDate che \u00e8 la data ed ora di visualizzazione del messaggio\r\n\t\t\/\/imposto come visualizzazione 1 minuti dopo la data specificata\r\n\t\tnotifica.fireDate = [dataNotifica dateByAddingTimeInterval:(1*60)];\r\n\t\r\n\t\t\/*Imposto il timezone per esser certo che la data e l'ora impostate siano sempre corrette,\r\n\t\t assegnando infatti l'oggetto timeZone, il fireDate viene regolato automaticamente\r\n\t\t quando ci sono cambiamenti di fuso orario, di default il timeZone \u00e8 \"nil\".\r\n\t\t *\/\r\n\t\tnotifica.timeZone = [NSTimeZone defaultTimeZone];\r\n\r\n\t\t\/\/Messaggio che verr\u00e0 visualizzato dall'iOS se la nostra applicazione \u00e8 spenta\r\n\t\tnotifica.alertBody = [NSString stringWithFormat:@\"%@ - notifica locale\",nome];\r\n\t\t\/\/Nome del pulsante per avviare la nostra applicazione\r\n\t\tnotifica.alertAction = @\"Dettagli\";\r\n\r\n\t\t\/\/Qui possiamo impostare un suono, per semplicit\u00e0 impostiamo il suono di default\r\n\t\tnotifica.soundName = UILocalNotificationDefaultSoundName;\r\n\t\r\n\t\t\/\/Aggiorniamo il badge dell'applicazione\r\n\t\tnotifica.applicationIconBadgeNumber = 1;\r\n\r\n\t\t\/\/aggiungiamo un dictionary con informazioni a piacere, in questo caso ho inserito il nome dell'evento\r\n\t\t\/\/ per utilizzarlo successivamente richiamandolo in base alla costante\r\n\t\tNSDictionary *infoDict = [NSDictionary dictionaryWithObjectsAndKeys:nome,chiaveNome, nil];\r\n\t\tnotifica.userInfo = infoDict;\r\n\r\n\t\t\/\/Impostiamo la nostra local notification \r\n\t\t[[UIApplication sharedApplication] scheduleLocalNotification:notifica];\r\n\r\n\t\t\/\/Distruggiamo l'oggetto solo se istanziato\r\n\t\tif (notifica){\r\n\t\t\t[notifica release];\r\n\t\t}\r\n\r\n\t}\r\n}\r\n<\/pre>\n<p>Intercettare una notifica locale quando l\u2019applicazione \u00e8 in esecuzione \u00e8 semplicissimo.<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n\/\/Metodo per intercettare le notifiche durante l'esecuzione dell'app\r\n- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notif {\r\n\t[self visualizzaMessaggio:[notif.userInfo objectForKey:chiaveNome] titolo:@\"Notifica intercettata\"];\r\n}\r\n<\/pre>\n<p>Questo \u00e8 il metodo per visualizzare i messaggi.<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n- (void) visualizzaMessaggio:(NSString*)message titolo:(NSString*)titoloFinestra {\r\n\tUIAlertView* alertView = [[UIAlertView alloc] initWithTitle:titoloFinestra message:message delegate:self cancelButtonTitle:@\"OK\" otherButtonTitles:nil];\r\n\t[alertView show];\r\n\tif (alertView) { \r\n\t\t[alertView release]; \r\n\t}\r\n}\r\n<\/pre>\n<p>Ci sono altre propriet\u00e0 che si possono impostare, ad esempio \u00e8 possibile gestire la &#8220;ripetizione&#8221; del messaggio, oppure cambiare l\u2019immagine di avvio dell\u2019applicazione quando questa viene richiamata da una local notification.<\/p>\n<p>Tutto \u00e8 come sempre dettagliato nella documentazione ufficiale:<\/p>\n<p><a href=\"http:\/\/developer.apple.com\/iphone\/library\/documentation\/iPhone\/Reference\/UILocalNotification_Class\/Reference\/Reference.html\" target=\"_blank\">http:\/\/developer.apple.com\/iphone\/library\/documentation\/iPhone\/Reference\/UILocalNotification_Class\/Reference\/Reference.html<\/a><\/p>\n<p>Qui c&#8217;\u00e8 un ottimo esempio scritto dalla Apple:<\/p>\n<p><a href=\" http:\/\/developer.apple.com\/iphone\/library\/documentation\/NetworkingInternet\/Conceptual\/RemoteNotificationsPG\/IPhoneOSClientImp\/IPhoneOSClientImp.html\" target=\"_blank\"><br \/>\nhttp:\/\/developer.apple.com\/iphone\/library\/documentation\/NetworkingInternet\/Conceptual\/RemoteNotificationsPG\/IPhoneOSClientImp\/IPhoneOSClientImp.html<\/a><\/p>\n<h4>Considerazioni finali<\/h4>\n<p>Come potete vedere grazie all&#8217;SDK \u00e8 tutto molto semplice, la classe <strong>UILocalNotification<\/strong> \u00e8 comunque migliorabile.<\/p>\n<p>Ad esempio si potrebbe migliorare la gestione della &#8220;cancellazione&#8221; di una local notification; attualmente infatti \u00e8 possibile cancellarla solo \u201cpassando\u201d la local notification che vogliamo eliminare, richiamando il seguente metodo:<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n- (void)cancelLocalNotification:(UILocalNotification *)notification\r\n<\/pre>\n<p>Richiamando questo metodo invece cancelleremo tutte le local notification impostate dalla nostra applicazione:<\/p>\n<pre lang=\"objc\" line=\"1\" escaped=\"true\">\r\n- (void)cancelAllLocalNotifications\r\n<\/pre>\n<p>Nella mia applicazione ho la necessit\u00e0 di visualizzare le notifiche in base ai dati inseriti dall&#8217;utente.<br \/>\nIl metodo di cancellazione di una notifica locale non mi aiuta molto nelle eventuali modifiche\/cancellazioni dei dati dell\u2019utente, dal momento che, per tenerne traccia, dovrei salvarmi l\u2019istanza creata e \u201clegarla\u201d al record sul database.<\/p>\n<p>Inoltre sarebbe molto dispendioso in termini di sviluppo tracciare tutte le modifiche dell\u2019utente con la possibilit\u00e0 di bug.<br \/>\nHo scelto una strada semplice che racchiude tutta la gestione in un unico punto.<br \/>\nAll&#8217;uscita dell\u2019applicazione cancello le local notifications e le riscrivo in base ai dati salvati dall\u2019utente; in tal modo sono sicuro di ricreare sempre le local notifications corrette.<\/p>\n<p>Fatemi sapere cosa ne pensate di questa nuova funzionalit\u00e0!<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/07\/T066-Test-Notifiche-Locali-iphone.zip\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/05\/download_icon.png\" alt=\"Icona Download\" title=\"download_icon\" width=\"33\" height=\"40\" class=\"alignnone size-full wp-image-3385\" \/><\/a> Se avete problemi con il tutorial, questo \u00e8 il <a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/07\/T066-Test-Notifiche-Locali-iphone.zip\">nostro file di progetto<\/a>.<br \/>\n<\/center><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Ciao a tutti, sono Rudy Trematerra, questo \u00e8 il mio primo articolo su devAPP.it ed ho scelto&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[365,364,367,368,366],"class_list":["post-4202","post","type-post","status-publish","format-standard","hentry","category-tutorial-pratici","tag-ios-4","tag-local-notification","tag-notifiche-locali-iphone","tag-rudy-trematerra","tag-uilocalnotification"],"acf":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/4202","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/comments?post=4202"}],"version-history":[{"count":4,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/4202\/revisions"}],"predecessor-version":[{"id":4209,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/4202\/revisions\/4209"}],"wp:attachment":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/media?parent=4202"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/categories?post=4202"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/tags?post=4202"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}