Dopo aver letto i primi passi con i Core Data, ci troviamo illuminati nel modo in cui funziona il Core Data e in che modo può aiutarci a sviluppare applicazioni ricche di dati. Tuttavia, la superficie era solo appena scalfita, e in alcune applicazioni potreste rimanere incerti su come implementare un determinato elemento di funzionalità.
Negli ultimi mesi ho lavorato con Core Data a un progetto per animali domestici. Si tratta di un'applicazione per inserire dati da un'API di servizi remoti, archiviare i dati in Core Data e visualizzarli in una raccolta di UITableViews. Nel corso dello sviluppo, è passato da un archivio dati basato su Elenco proprietà (* shudder *) a un archivio di SQL Data Core. Dopo tre ricostruzioni complete e molte lunghe notti di debug, la mia applicazione è finalmente diventata un progetto veloce, privo di crash e senza perdite di memoria. Per me, l'uso di Core Data ha reso la mia applicazione ciò che era destinato a essere, e condividerò molto di ciò che ho imparato con te in questo e in altri articoli futuri.
Per questo articolo, utilizzeremo la precedente applicazione LapTimer e dimostreremo di eseguire migrazioni leggere.
Quando sviluppi un'applicazione non otterrai quasi mai lo schema correttamente la prima volta. Pertanto, i dati principali supportano il controllo delle versioni dello schema e la migrazione dei dati. Ciò consente di definire una nuova versione dello schema dei Core Data aggiungendo un nuovo attributo o entità allo store. Quindi definire come deve migrare lo store da una modifica all'altra.
Core Data gestisce le versioni dello schema in modo diverso rispetto ad altri framework che potresti aver usato in passato. Quando si passa allo sviluppo e si richiede un nuovo attributo o entità, il processo di aggiunta è creando un nuovo file xcdatamodel per la propria applicazione. Questo nuovo file sarà versionato, avrà un numero incrementale nel nome del file ed è distinto dalle versioni precedenti dello schema. Nell'applicazione LapTimer, creare la nuova versione del modello di dati. Clicca sul file xcdatamodel nella tua applicazione e poi vai alla voce di menu su: Progettazione> Modello dati> Aggiungi versione modello.
Ora si avrà un albero xcdatamodel, il genitore è un nuovo file xcdatamodel, con una nuova versione dello schema denotata dal numero incrementale. Inoltre, c'è un segno di spunta verde contro il vecchio schema. Questo indica quale schema è attivo e l'applicazione che userà. È importante notare che la scelta immediata della nuova versione potrebbe causare alcuni problemi di sviluppo. Poiché non abbiamo ancora impostato una migrazione per questo nuovo schema, se dovessimo rendere attivo il nuovo schema, il simulatore o il dispositivo si guasteranno e si bloccheranno all'avvio. Come dimostrazione, dai un'occhiata all'errore qui sotto, è comune per ciò che le persone incontrano al primo tentativo:
In pratica sta solo dicendo "Ehi, hai cambiato lo schema DB attivo e sono bloccato su una versione precedente". Ciò impedisce all'applicazione di conflitti ed errori con la modifica dello schema dell'archivio dati di base. Fa un confronto basato sui dettagli dello schema con cui sta operando il negozio. Se viene fornita una nuova versione dello schema da utilizzare ma non corrisponde a ciò per cui è stata configurata o migrata, viene visualizzato questo errore.
Quindi, come possiamo superare questo? Bene, ci sono due opzioni:
Questa è una funzionalità semplice e automatica di Core Data, ma è limitata a semplici migrazioni, quindi il motivo è leggero. È possibile utilizzare questo metodo solo se le modifiche sono tra le seguenti:
Nota: prima di immergerci, se stai lavorando al progetto LapTimer dovrai costruire il progetto prima di iniziare. Assicurati che xcdatamodel sia la prima versione con cui è stata creata l'applicazione. In questo modo sarai in grado di vedere il lavoro di migrazione.
A dimostrazione, l'applicazione LapTimer avrà l'entità evento modificata in Lap. Con questo dobbiamo anche aggiornare le classi Event.h ed Event.m e qualsiasi occorrenza di quelli nell'applicazione. Con una coppia di funzionalità Xcode questo è indolore.
Quindi, nella nuova versione di xcdatamodel creata in precedenza, eseguirò la modifica semplicemente cambiando i valori nel pannello dei dettagli dell'entità. Ora dobbiamo impostare "Renaming Identifier" su Event. Quindi, nello stesso pannello, fai clic sulla chiave inglese / chiave inglese e inserisci "Evento" nel campo Identificativo di rinominazione, in questo modo:
Il passo successivo è dire a Core Data che può eseguire migrazioni leggere all'avvio. Facendo riferimento all'applicazione LapTimer, nel file LapTimerAppDelegate.m sarà necessario aggiungere del codice al metodo persistentStoreCoordinator - (NSPersistentStoreCoordinator *):
- (NSPersistentStoreCoordinator *) persistentStoreCoordinator if (persistentStoreCoordinator! = Nil) return persistentStoreCoordinator; NSURL * storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @ "LapTimer.sqlite"]]; NSError * error = nil; persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]]; NSDictionary * options = [NSDictionary dictionaryWithObjectsAndKeys: [NSNumber numberWithBool: YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool: YES], NSInferMappingModelAutomaticallyOption, nil]; if (! [persistentStoreCoordinator addPersistentStoreWithType: NSSQLiteStoreType configuration: nil URL: storeUrl options: options error: & error]) / * Sostituire questa implementazione con il codice per gestire l'errore in modo appropriato. abort () causa l'applicazione per generare un registro di arresto anomalo e terminare. Non si dovrebbe usare questa funzione in un'applicazione di spedizione, sebbene possa essere utile durante lo sviluppo. Se non è possibile ripristinare l'errore, visualizzare un pannello di avviso che indica all'utente di uscire dall'applicazione premendo il pulsante Home. I motivi tipici di un errore qui includono: * L'archivio persistente non è accessibile * Lo schema per l'archivio persistente non è compatibile con il modello oggetto gestito corrente Controllare il messaggio di errore per determinare quale fosse il problema reale. * / NSLog (@ "Errore non risolto% @,% @", errore, [errore userInfo]); abort (); return persistentStoreCoordinator;
Il codice aggiunto era le opzioni NSDictionary che diranno a Core Data di eseguire migrazioni automatiche.
Abbiamo quasi finito. Il passaggio successivo consiste nel modificare i file di classe per l'entità Event per riflettere il nuovo nome. Per fare questo usiamo la mia caratteristica preferita di Xcode, la funzione Refactor. Come suggerito dal nome, questa funzione effettuerà il refactoring e eseguirà una ricerca e sostituzione più avanzata sul progetto per situazioni come queste.
Per fare ciò è necessario aprire Event.m e selezionare il testo "Event" su quel file. Quindi vai a: Modifica> Refactor (Cmd + Shift + J). Su apparirà una finestra con opzioni e campi come lo screenshot qui sotto. Inserisci la parola Lap nel campo "Event to". Fai clic sull'anteprima e otterrai l'output di tutte le modifiche:
Se vuoi vedere cosa farà, fai clic su uno dei file nel pannello dei risultati e ti mostrerà i dettagli di ciò che cambierà. Rinominerà anche i file Event.h ed Event.m per noi. Solo per notare, i precedenti file xcdatamodel con la particolare classe NSManagedObject da sostituire avranno una leggera modifica. Cambierà il nome della classe dell'entità, non il suo nome dell'entità, quindi se un dispositivo deve passare attraverso la migrazione può ancora utilizzare la classe entità NSManagedObject e i metodi correlati.
Hit apply. Questo è tutto. Come precauzione di sicurezza prenderà anche uno Snapshot, un'altra grande caratteristica di XCode. Quindi se tutto va storto puoi semplicemente tornare all'istantanea precedente, proprio come Time Machine ma meno tutte le stelle e l'interfaccia utente di swirly galaxy.
Sfortunatamente, questo non cattura tutti i cambiamenti necessari. Ci sono ancora alcuni bit dell'applicazione LapTimer che fanno riferimento a Event. Quindi un rapido Trova e sostituisci è in ordine. Vai a: Modifica> Trova nel progetto. Con la nuova finestra entra in Event come find e Lap come sostituto. Deseleziona "Ignora maiuscole / minuscole" perché vogliamo solo selezionare la rigorosa maiuscola del ritrovamento. Quindi cambia il menu a discesa dove è selezionato "Contiene" e seleziona "Parole intere". Questo restringerà la ricerca esattamente a ciò di cui abbiamo bisogno.
Clicca Trova. Rivedere le modifiche Se tutto è andato a buon fine, eseguire la sostituzione!
Quindi abbiamo creato una nuova versione dello schema, apportato alcune modifiche e ora è il momento di inserire l'applicazione nel nuovo schema.
Niente di complicato qui. Seleziona il nuovo schema che desideri impostare come attivo e vai a: Design> Modello dati> Imposta la versione corrente. Il segno di spunta verde passerà al nuovo schema ed è tutto pronto per andare.
Costruisci ed esegui l'applicazione. Tutto dovrebbe andare bene e l'applicazione dovrebbe aprirsi, migrare ed eseguire. Non noterai affatto questa migrazione, nemmeno un output di debugger. Ma il fatto che il codice sia in esecuzione e funzionante è la prova che è stato migrato.
Quindi l'applicazione ora ha un nome di entità modificato. Questo può accadere di volta in volta nello sviluppo di qualsiasi applicazione. È possibile aggiungere nuove proprietà con questo metodo di migrazione leggero con lo stesso processo.
Se è necessario modificare il tipo di una proprietà o apportare modifiche più avanzate, sarà necessario effettuare l'immersione nella migrazione dell'oggetto del modello di mappatura. Questo è un metodo più avanzato di ciò che abbiamo eseguito, richiedendo configurazioni e codici aggiuntivi. La documentazione Apple iOS ha una buona esperienza di questo avanzato processo di migrazione.