{"id":3001,"date":"2010-04-13T11:06:01","date_gmt":"2010-04-13T09:06:01","guid":{"rendered":"http:\/\/www.devapp.it\/wordpress\/?p=3001"},"modified":"2011-03-01T15:49:42","modified_gmt":"2011-03-01T14:49:42","slug":"t032-sfruttiamo-nsuserdefaults-per-salvare-dati-delle-nostre-applicazioni-iphone","status":"publish","type":"post","link":"https:\/\/www.devapp.it\/wordpress\/t032-sfruttiamo-nsuserdefaults-per-salvare-dati-delle-nostre-applicazioni-iphone\/","title":{"rendered":"T#032 &#8211; Sfruttiamo NSUserDefaults per salvare dati delle nostre applicazioni iPhone"},"content":{"rendered":"<p><a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/04\/Schermata-2010-04-12-a-16.32.27.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/04\/Schermata-2010-04-12-a-16.32.27.png\" alt=\"\" width=\"48\" height=\"91\" class=\"alignleft size-full wp-image-3044\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/04\/Schermata-2010-04-12-a-16.32.27.png 383w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/04\/Schermata-2010-04-12-a-16.32.27-157x300.png 157w\" sizes=\"auto, (max-width: 48px) 100vw, 48px\" \/><\/a> Se state sviluppando un&#8217;applicazione iPhone, molto probabilmente potreste aver bisogno di salvare dei dati durante l&#8217;uso dell&#8217;applicazione, da ritrovare poi ai successivi avvii del programma. Potreste sfruttare quello che vi proponiamo oggi per salvare, ad esempio, dei dati di configurazione per le vostre Applicazioni. Se questo \u00e8 quello che cercate, sappiate che in nostro aiuto arriva <strong>NSUserDefaults<\/strong>, la quale ci permette proprio di salvare alcuni contenuti. Questi, una volta salvati, appariranno anche se chiudiamo e riapriamo la nostra app.<!--more--><\/p>\n<p>Come esempio costruiremo un&#8217;applicazione semplice, in cui dovremmo inserire del testo in una <em>UITextField<\/em>. Questo testo verr\u00e0 salvato e faremo in modo di farlo riapparire poi al riavvio della nostra App. Diciamo che faremo un &#8220;Hello World!&#8221; avanzato!<\/p>\n<p>Prima di tutto, apriamo <em>Xcode<\/em>, creiamo un nuovo progetto di tipo &#8220;<em>View-based Application<\/em>&#8221; e chiamiamolo &#8220;<em>SalvaStringa<\/em>&#8221; (o come preferite). Apriamo il file <em>SalvaStringaViewController.h<\/em> e dichiariamo gli outlets che useremo con le relative propriet\u00e0 ed un&#8217;azione:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\n@interface SalvaStringaViewController : UIViewController {\r\n\tIBOutlet UITextField *campo;\r\n\tIBOutlet UILabel *testo;\r\n}\r\n\r\n- (IBAction)leggi;\r\n\r\n@property (nonatomic, retain) IBOutlet UITextField *campo;\r\n@property (nonatomic, retain) IBOutlet UILabel *testo;\r\n\r\n@end\r\n<\/pre>\n<p>Come vedete tutto molto semplice, si tratta di una semplice Text Field, una Label di Testo e un&#8217;azione che useremo poi per leggere il contenuto del testo.<\/p>\n<p>Apriamo il file <em>SalvaStringaViewController.xib<\/em> e passiamo a InterfaceBuilder. Costruiamo quindi la semplice interfaccia grafica, infine, colleghiamo dal pannello delle connessioni del nostro File&#8217;s Owner, i due outlets e il metodo creati precedentemente con Xcode con i nostri oggetti appena disegnati.<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/04\/Schermata-2010-04-12-a-16.23.44.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/04\/Schermata-2010-04-12-a-16.23.44.png\" alt=\"\" width=\"418\" height=\"340\" class=\"aligncenter size-full wp-image-3037\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/04\/Schermata-2010-04-12-a-16.23.44.png 627w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/04\/Schermata-2010-04-12-a-16.23.44-300x244.png 300w\" sizes=\"auto, (max-width: 418px) 100vw, 418px\" \/><\/a><br \/>\n<\/center><\/p>\n<p>Modifichiamo ora il file &#8220;<em>SalvaStringaViewController.m<\/em>&#8221; come segue:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\n@synthesize campo, testo;\r\n\r\n- (IBAction)leggi{\r\n\tNSString *stringaTesto = campo.text;\r\n\ttesto.text = [[NSString alloc] initWithFormat:@\"%@\", stringaTesto];\r\n\t\r\n\tNSString *testoInserito = testo.text;\r\n\tNSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];\r\n\t[defaults setObject:testoInserito forKey:@\"ciao\"];\r\n\t[defaults synchronize];\r\n}\r\n<\/pre>\n<p>Analizziamo il codice. Innanzitutto grazie a <strong>@synthesize<\/strong> saremo in grado di utilizzare tutte le propriet\u00e0 dei nostri oggetti dichiarati in precedenza; nelle prime due linee abbiamo semplicemente letto il testo che l&#8217;utente inserisce nella Text Field e lo abbiamo fatto apparire nella nostra label. Nelle altre quattro, avviene il salvataggio del testo: tramite <strong>NSUserDefaults<\/strong> settiamo un oggetto (<em>setObject:<\/em>) e una chiave collegata con esso (<em>forKey:<\/em>).<\/p>\n<p>Sempre nel file di implementazione (.m), scommentiamo il metodo <em>viewDidLoad<\/em>, che si trova un po&#8217; pi\u00f9 in basso e, dopo <em>[super viewDidLoad];<\/em>, scriviamo le seguenti istruzioni:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\nNSString *testoSalvato = [[NSUserDefaults standardUserDefaults] objectForKey:@\"ciao\"];\r\n\tif (testoSalvato == nil) {\r\n\t\ttesto.text = @\"Non hai ancora inserito il tuo nome\";\r\n\t} else {\r\n\t\ttesto.text = [[NSString alloc] initWithFormat:@\"Ciao %@\", testoSalvato];\r\n\t}\r\n<\/pre>\n<p>Questo codice verr\u00e0 eseguito al caricamento della vista. Come potete vedere, abbiamo settato una NSString che riprende le informazioni necessarie da un oggetto di tipo NSUserDefaults con chiave &#8220;ciao&#8221; (quello di prima). Successivamente tramite un semplicissimo &#8220;<em>if &#8211; else<\/em>&#8221; diciamo cosa deve fare l&#8217;app in caso in cui non ci siano dati salvati e in caso che questi, invece, siano presenti.<\/p>\n<p>Come ultimissima cosa, sempre nel file .m, inseriamo questo metodo per far nascondere la tastiera alla pressione del pulsante &#8220;Invio&#8221;:<\/p>\n<pre lang=\"objc\" escaped=\"true\">\r\n- (BOOL)textFieldShouldReturn:(UITextField *)textField{\r\n\t[textField resignFirstResponder];\r\n\treturn YES;\r\n}\r\n<\/pre>\n<p>Riaprite ora il file .xib e dopo aver cliccato sulla Text Field, andate nel pannello dele connessioni e collegate l&#8217;unico elemento (delegate) sotto gli Outlets al File&#8217;s Owner. (ATTENZIONE a questo passaggio, fonte di errore molto comune).<\/p>\n<p>Abbiamo conluso la nostra applicazione!  Cliccate su <em>Build and Run<\/em>, inserite un testo nella Text Field, premete il bottone ed ecco il risultato:<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/04\/Schermata-2010-04-12-a-16.31.44.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/04\/Schermata-2010-04-12-a-16.31.44.png\" alt=\"\" width=\"389\" height=\"731\" class=\"aligncenter size-full wp-image-3043\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/04\/Schermata-2010-04-12-a-16.31.44.png 389w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/04\/Schermata-2010-04-12-a-16.31.44-159x300.png 159w\" sizes=\"auto, (max-width: 389px) 100vw, 389px\" \/><\/a><br \/>\n<\/center><\/p>\n<p>Se chiudete ora e riaprite l&#8217;applicazione questo sar\u00e0 il risultato:<\/p>\n<p><center><br \/>\n<a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/04\/Schermata-2010-04-12-a-16.32.27.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/04\/Schermata-2010-04-12-a-16.32.27.png\" alt=\"\" width=\"383\" height=\"731\" class=\"aligncenter size-full wp-image-3044\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/04\/Schermata-2010-04-12-a-16.32.27.png 383w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2010\/04\/Schermata-2010-04-12-a-16.32.27-157x300.png 157w\" sizes=\"auto, (max-width: 383px) 100vw, 383px\" \/><\/a><br \/>\n<\/center><\/p>\n<p>Alla prossima \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Se state sviluppando un&#8217;applicazione iPhone, molto probabilmente potreste aver bisogno di salvare dei dati durante l&#8217;uso dell&#8217;applicazione,&#8230;<\/p>\n","protected":false},"author":40,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[174,173,5,1],"class_list":["post-3001","post","type-post","status-publish","format-standard","hentry","category-tutorial-pratici","tag-nsstring","tag-nsuserdefaults","tag-objective-c","tag-tutorial-pratici"],"acf":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/3001","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\/40"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/comments?post=3001"}],"version-history":[{"count":17,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/3001\/revisions"}],"predecessor-version":[{"id":6012,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/3001\/revisions\/6012"}],"wp:attachment":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/media?parent=3001"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/categories?post=3001"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/tags?post=3001"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}