{"id":11035,"date":"2014-10-09T15:50:00","date_gmt":"2014-10-09T13:50:00","guid":{"rendered":"http:\/\/www.devapp.it\/wordpress\/?p=11035"},"modified":"2014-10-09T15:51:47","modified_gmt":"2014-10-09T13:51:47","slug":"come-gestire-la-persistenza-nelle-applicazioni-ios-con-realm","status":"publish","type":"post","link":"https:\/\/www.devapp.it\/wordpress\/come-gestire-la-persistenza-nelle-applicazioni-ios-con-realm\/","title":{"rendered":"Come gestire la persistenza nelle applicazioni iOS con Realm"},"content":{"rendered":"<p>Tutte le applicazioni hanno bisogno di salvare delle informazioni in modo persistente all\u2019interno del device, che siano soltanto delle opzioni di configurazione, piuttosto che una struttura dati pi\u00f9 complessa.<br \/>\nSu iOS si hanno a disposizione diverse teniche per raggiungere lo scopo, che vanno dal salvare un file di testo, serializzare delle classi base in file xml (plist), utilizzare il protocollo NSCoding e la classe NSKeyedArchiver per serializzare gli oggetti in un file binario oppure per strutture pi\u00f9 complesse si pu\u00f2 utilizzare un database come SQLite,\u00a0ultralite o un <a href=\"http:\/\/it.wikipedia.org\/wiki\/Object-relational_mapping\" target=\"_blank\">ORM<\/a> come Coredata.<br \/>\nOggi al ventaglio di opzioni si aggiunge un nuovo framework: <strong>Realm<\/strong> (<a href=\"http:\/\/realm.io\" target=\"_blank\">homepage<\/a>), che si presenta come &#8220;<strong>&#8230;a mobile database: a replacement for SQLite &amp; Core Data<\/strong>&#8220;. Le premesse sono importanti, vediamo quindi il framework all&#8217;opera.<\/p>\n<p><a href=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2014\/10\/realm-a-replacement-for-SQLite-and-Core-Data.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2014\/10\/realm-a-replacement-for-SQLite-and-Core-Data.png\" alt=\"realm-a-replacement-for-SQLite-and-Core-Data\" width=\"642\" height=\"336\" class=\"alignnone size-full wp-image-11037\" srcset=\"https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2014\/10\/realm-a-replacement-for-SQLite-and-Core-Data.png 642w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2014\/10\/realm-a-replacement-for-SQLite-and-Core-Data-300x157.png 300w, https:\/\/www.devapp.it\/wordpress\/wp-content\/uploads\/2014\/10\/realm-a-replacement-for-SQLite-and-Core-Data-500x261.png 500w\" sizes=\"auto, (max-width: 642px) 100vw, 642px\" \/><\/a><\/p>\n<p>Per installare il framework la via pi\u00f9 facile \u00e8 tramite cocoapods, basta infatti aggiungere:<\/p>\n<pre class=\"lang:sh decode:true \">pod 'Realm'<\/pre>\n<p>al Podfile per poter iniziare ad usarlo.<\/p>\n<p>Il framework richiede che gli oggetti da memorizzare all&#8217;interno del database siano subclass di <strong>RLMObject<\/strong> un po&#8217; come con CoreData e i suoi NSManagedObject, ma le similitudini si fermano qui, perch\u00e9 con Realm \u00e8 possibile scrivere direttamente le nostre classi senza passare dal file xcdatamodel.<br \/>\nQuindi supponiamo che si voglia salvare oggetti di tipo &#8216;Cutomer&#8217; la classe potrebbe essere cos\u00ec:<\/p>\n<pre class=\"lang:objc decode:true \" >#import \"RLMObject.h\"\r\n@interface Customer : RLMObject\r\n@property (nonatomic) NSString *firstName;\r\n@property (nonatomic) NSString *lastName;\r\n@property (nonatomic) NSString *address;\r\n@property (nonatomic) NSString *city;\r\n@property (nonatomic) NSString *zipCode;\r\n- (NSString *)fullAddress;\r\n@end\r\n<\/pre>\n<p>e l&#8217;aspetto forse pi\u00f9 comodo \u00e8 che gli oggetti possono essere creati direttamente, senza passare da NSContextManager, quindi quando vorr\u00f2 creare un nuovo <em>Customer<\/em> dovr\u00f2 semplicemente scrivere:<\/p>\n<pre class=\"lang:objc decode:true \" >Customer *newCustomer = [[Customer alloc] init];\r\n[newCustomer setFirstName:@\"Mario\"];\r\n[newCustomer setLastName:@\"Rossi\"];\r\n[newCustomer setAddress:@\"Viale Zara 1\"];\r\n[newCustomer setCity:@\"Milano\"];\r\n[newCustomer setZipCode:@\"20144\"];<\/pre>\n<p>Ma la parte pi\u00f9 importante \u00e8 come si salvano gli oggetti? A differenza di coredata\/sqlite non \u00e8 necessaria alcuna configurazione, esiste infatti una classe singleton gi\u00e0 configurata per gli utilizzi pi\u00f9 comuni ed \u00e8 gi\u00e0 pronta da utilizzare. Possiamo quindi accedere alla nostra istanza del &#8220;database&#8221; in questo modo:<\/p>\n<pre class=\"lang:objc decode:true \" >RLMRealm *realm = [RLMRealm defaultRealm];<\/pre>\n<p>Per Realm tutte le operazioni di scrittura devono essere gestite all&#8217;interno di una transaction (chi \u00e8 pratico di database sa di cosa sto parlando):<\/p>\n<pre class=\"lang:objc decode:true \" >[realm beginWriteTransaction];\r\n\/\/ qui inseriamo il codice per salvare l'oggetto\r\n[realm commitWriteTransaction];<\/pre>\n<p>Il codice per salvare il nostro customer nel database non poteva essere pi\u00f9 semplice infatti basta digitare:<\/p>\n<pre class=\"lang:objc decode:true \" >[realm addObject:newCustomer];<\/pre>\n<p>per salvare in modo permanente il customer all&#8217;interno del database.<\/p>\n<p>Riepilogando il nostro codice per creare e salvare il customer si presenta cos\u00ec<\/p>\n<pre class=\"lang:objc decode:true \" >Customer *newCustomer = [[Customer alloc] init];\r\n[newCustomer setFirstName:@\"Mario\"];\r\n[newCustomer setLastName:@\"Rossi\"];\r\n[newCustomer setAddress:@\"Viale Zara 1\"];\r\n[newCustomer setCity:@\"Milano\"];\r\n[newCustomer setZipCode:@\"20144\"];\r\n\r\nRLMRealm *realm = [RLMRealm defaultRealm];\r\n[realm beginWriteTransaction];\r\n[realm addObject:newCustomer]; \/\/ [realm commitWriteTransaction];<\/pre>\n<p>Potrebbe essere pi\u00f9 facile di cos\u00ec?<\/p>\n<h2>Operazioni CRUD<\/h2>\n<p>Abbiamo visto come creare un nuovo customer e come salvarlo nel database, in termini di operazioni CRUD (<a href=\"http:\/\/en.wikipedia.org\/wiki\/Create,_read,_update_and_delete\" target=\"_blank\">http:\/\/en.wikipedia.org\/wiki\/Create,_read,_update_and_delete<\/a>) abbiamo visto la &#8216;C&#8217; di create. Ma da un framework il cui obiettivo \u00e8 sostituire coredata ci aspettiamo che anche le altre operazioni siano gestite in modo altrettanto semplice.<\/p>\n<h3>&#8216;R&#8217; come Read:<\/h3>\n<p>Si possono effettuare delle select sul database partendo direttamente dal modello (ActiveRecord design pattern) infatti tutte le subclass di RLMObject ereditano metodi come: objectsWhere:, objectsWithPredicate:<\/p>\n<h3>&#8216;U&#8217; come Update:<\/h3>\n<p>Per aggiornare un record bisogna editare direttamente l&#8217;oggetto associato, newCustomer.firstName = @&#8221;Luigi&#8221;; e il nuovo valore sar\u00e0 automaticamente salvato nel database<\/p>\n<h3>&#8216;D&#8217; come Delete:<\/h3>\n<p>La cancellazione si fa a partire dal realm utilizzando i metodi: deleteObjects: e deleteObject:<\/p>\n<h2>Come approfondire<\/h2>\n<p>Se l&#8217;articolo vi ha incuriosito e volete approfondire lo studio di questo framework, date un&#8217;occhiata alla documentazione (ben fatta) presente sul sito <a href=\"http:\/\/realm.io\/docs\/cocoa\/0.86.2\/\" target=\"_blank\">http:\/\/realm.io\/docs\/cocoa\/0.86.2\/<\/a> dove \u00e8 spiegato come gestire le relazioni o come ricevere delle notifiche ogni volta che un record viene aggiornato (utile per aggiornare la UI), come utilizzare Realm per salvare dati provenienti da un webserice rest and so on.<\/p>\n<h2>Discaimer<\/h2>\n<p>Realm \u00e8 un&#8217;azienda alla quale non sono e non siamo legati in alcun modo. Al momento il prodotto \u00e8 free e opensource, ma non mi meraviglierebbe una versione a pagamento in un prossimo futuro se il prodotto dovesse avere particolarmente successo. Per info visitare la pagina <a href=\"http:\/\/realm.io\/pricing\/\" target=\"_blank\">http:\/\/realm.io\/pricing\/<\/a><\/p>\n<p>Buona programmazione a tutti!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Tutte le applicazioni hanno bisogno di salvare delle informazioni in modo persistente all\u2019interno del device, che siano&#8230;<\/p>\n","protected":false},"author":53,"featured_media":11037,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[8,481],"tags":[1400,1399,1401,1397,1398],"class_list":["post-11035","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-guide-varie","category-risorse-utili","tag-alternativa-sqlite-ios","tag-alternative-a-core-data-ios","tag-database-ios","tag-persistenza-dati-ios","tag-realm-ios"],"acf":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/11035","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\/53"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/comments?post=11035"}],"version-history":[{"count":6,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/11035\/revisions"}],"predecessor-version":[{"id":11042,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/posts\/11035\/revisions\/11042"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/media\/11037"}],"wp:attachment":[{"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/media?parent=11035"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/categories?post=11035"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devapp.it\/wordpress\/wp-json\/wp\/v2\/tags?post=11035"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}