Arbeide med Core Data Schema Versjonering og Lettvekts Migreringer

Etter å ha lest Første trinn med Core Data, finner vi oss opplyst i hvordan Core Data fungerer, og hvordan det kan hjelpe oss med å utvikle datarike applikasjoner. Overflaten ble imidlertid bare skrapt, og i noen programmer kan du bli lurt å lure på hvordan du implementerer en viss funksjonalitet.

Min erfaring med kjerne data

I de siste månedene har jeg jobbet med Core Data på et kjæledyrprosjekt. Det er et program for å trekke inn data fra en ekstern tjeneste API, lagre dataene i Core Data, og vise den i en samling av UITableViews. I løpet av utviklingen har det gått fra en eiendomsliste basert datalager (* shudder *) til nå en Core Data SQL-butikk. Etter tre komplette gjenoppbygginger og mange lange netter med feilsøking, har søknaden min endelig blitt et raskt, krasjfritt og minnefritt prosjekt. For meg har Core Data gjort søknaden min hva den var ment å være, og jeg vil dele mye av det jeg har lært med deg i denne og fremtidige artikler.

For denne artikkelen vil vi bygge videre på det forrige LapTimer-programmet og demonstrere å utføre lette migrasjoner.

Schemaendringer, Versjonering og Migrasjoner

Når du utvikler et program, vil du nesten aldri få skjemaet riktig første gang. Så, Core Data har støtte for skjemaversjonering og dataoverføring. Dette lar deg definere en ny versjon av Core Data-skjemaet ved å legge til et nytt attributt eller en enhet i butikken. Definer deretter hvordan butikken må migrere fra en endring til en annen.

Opprette en ny xcdatamodel

Core Data håndterer skjema versjoner annerledes enn noen andre rammer du tidligere har brukt. Når du går gjennom utvikling og krever et nytt attributt eller enhet, er prosessen med å legge til disse ved å opprette en ny xcdatamodel-fil for søknaden din. Denne nye filen blir versjonert, har et inkrementalt nummer i filnavnet, og er forskjellig fra eldre skjermversjoner. I LapTimer-applikasjonen lager du den nye Datamodellversjonen. Klikk på xcdatamodel-filen i søknaden din, og naviger deretter til menyelementet på: Design> Datamodell> Legg til modellversjon.

Du vil nå ha et xcdatamodel-tre, forelderen er en ny xcdatamodel-fil, med en ny skjemaversjon betegnet med inkrementalnummeret. Det er også et grønt tikk mot det gamle skjemaet. Dette indikerer hvilket skjema som er aktivt og applikasjonen den skal bruke. Det er viktig å merke seg at å velge den nye versjonen med en gang kan forårsake noen problemer i utviklingen. Siden vi ikke har konfigurert en migrering for dette nye skjemaet ennå, hvis vi skulle gjøre det nye skjemaet det aktive, vil Simulator eller Enhet feil og krasje ved oppstart. Som en demonstrasjon, ta en titt på feilen nedenfor, det er vanlig for det folk møter på deres første forsøk:

Det er egentlig bare å si "Hei, du har endret det aktive DB-skjemaet og jeg sitter fast i en eldre versjon." Dette forhindrer at programmet kjøres fra konflikter og feil med Core Data Store-skjemaet. Det gjør en sammenligning basert på detaljene i skjemaet som butikken opererer med. Hvis det er gitt en ny skjemaversjon å bruke, men det stemmer ikke overens med hva det har blitt satt opp eller migrert til, så får du denne feilen.

Så, hvordan kommer vi forbi dette? Vel, det er to alternativer:

  1. Hvis appen er i utvikling, og du bryr deg ikke om data i programmet, sletter du bare programmet fra enheten og installerer det på nytt. Det vil slette butikken og innholdet, men det vil opprette appen med det nye skjemaet. Dette er bare et alternativ i utviklingen.
  2. Bruk lettvektsoverføring for å automatisk ta vare på små skjemaendringer når du lager dem. Dette er begrenset til bare noen få migreringer som er detaljert nedenfor.

Lettvektsoverføring

Dette er en enkel å bruke og en automatisk funksjon av Core Data, men det er begrenset til bare enkle migreringer, derfor årsaken til at den er lett. Du kan bare bruke denne metoden hvis endringene er blant følgende:

  • Legge til et nytt attributt / eiendom til en enhet.
  • Endre navn på en enhet eller et attributt / eiendom hvis "Renaming Identifier" er gitt.
  • Endre en attributt / egenskap til valgfritt eller ikke-valgfritt, om det krever en verdi ved opprettelse.

Merk: Før vi dykker inn, hvis du jobber med LapTimer-prosjektet, må du bygge prosjektet før vi starter. Pass på at den aktive xcdatamodellen er den første versjonen som programmet ble bygget med. På denne måten vil du kunne se migreringsarbeidet.

Som en demonstrasjon skal LapTimer-programmet få Event-enheten endret til Lap. Med dette må vi også oppdatere Event.h og Event.m klassene og eventuelle forekomster av de som er i applikasjonen. Med et par nifty Xcode funksjoner er dette smertefritt.

Så, i den nye versjonen av xcdatamodellen vi opprettet tidligere, skal jeg gjøre endringen ved å bare endre verdiene i enhetens detaljeringspanel. Nå må vi sette 'Renaming Identifier' til Event. Så i samme panel klikker du på nøkkel / skiftenøkkel og skriver inn "Event" i feltet Renaming Identifier, slik som:

Det neste trinnet er å fortelle Core Data at den kan utføre lette migrasjoner ved oppstart. Når du henviser til LapTimer-programmet, i filen LapTimerAppDelegate.m, må vi legge til kode i - (NSPersistentStoreCoordinator *) persistentStoreCoordinator-metoden:

 - (NSPersistentStoreCoordinator *) persistentStoreCoordinator if (persistentStoreCoordinator! = Null) return persistentStoreCoordinator;  NSURL * storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @ "LapTimer.sqlite"]]; NSError * error = nil; persistentStoreCoordinator = [[NSPersistentStoreCoordinator allokering] initWithManagedObjectModel: [self managedObjectModel]]; NSDictionary * options = [NSDictionary DictionaryWithObjectsAndKeys: [NSNummer nummerWithBool: YES], NSMigratePersistentStoresAutomaticallyOption, [NSNummer nummerWithBool: YES], NSInferMappingModelAutomaticallyOption, null]; hvis (! [persistentStoreCoordinator addPersistentStoreWithType: NSSQLiteStoreType konfigurasjon: null URL: storeUrl alternativer: opsjonsfeil: & feil]) / * Erstatt denne implementeringen med kode for å håndtere feilen på riktig måte. avbryte () forårsaker at programmet skal generere en krasjlogg og avslutte. Du bør ikke bruke denne funksjonen i et fraktprogram, selv om det kan være nyttig under utviklingen. Hvis det ikke er mulig å gjenopprette fra feilen, viser du et varselpanel som instruerer brukeren om å avslutte programmet ved å trykke på Hjem-knappen. Typiske grunner til en feil her inkluderer: * Den vedvarende butikken er ikke tilgjengelig * Skjemaet for den vedvarende butikken er uforenlig med gjeldende objektmodell. Kontroller feilmeldingen for å finne ut hva det egentlige problemet var. * / NSLog (@ "Uoppløst feil% @,% @", feil, [feil brukerInfo]); avbryte();  returnere persistentStoreCoordinator;  

Koden som ble lagt til var alternativene NSDictionary som vil fortelle Core Data å utføre automatiske migreringer.

Vi er nesten ferdige. Det neste trinnet er å endre klassefilene for hendelsesenheten for å gjenspeile det nye navnet. For å gjøre dette bruker vi min favorittfunksjon i Xcode, Refactor-funksjonen. Som underforstått av navnet, vil denne funksjonen refactor og gjøre en mer avansert finne og erstatt på prosjektet ditt for situasjoner som disse.

For å gjøre dette må du åpne Event.m og velg teksten 'Event' på den filen. Deretter går du til: Rediger> Refactor (Cmd + Shift + J). Up vil pope et vindu med alternativer og felt som skjermbildet nedenfor. Skriv inn ordet Lap i feltet 'Event to'. Klikk forhåndsvisning, og du vil få resultatet av alle endringene:

Hvis du vil lytte til hva dette vil gjøre, klikk så på en av filene i resultatpanelet, og det vil vise deg detaljer om hva det vil endre. Det vil også omdøpe Event.h og Event.m-filene for oss. Bare for å merke seg, tidligere xcdatamodel-filer med den spesielle NSManagedObject-klassen som ble erstattet, vil ha en liten endring. Det vil endre klassenavnet til enheten, ikke navnet på enheten, så hvis en enhet må gå gjennom migrering, kan den fortsatt bruke enhetene NSManagedObject klasse og relaterte metoder.

Hit gjelder. Det er det. Som en sikkerhetsforanstaltning vil det også ta et øyeblikksbilde, en annen flott funksjon av XCode. Så hvis alt går galt, kan du bare gå tilbake til forrige øyeblikksbilde, akkurat som Time Machine, men minus alle stjernene og Swirly Galaxy UI.

Dessverre tar det ikke alle endringene som trengs. Det er fortsatt noen biter av LapTimer-programmet som refererer til Event. Så en rask Find & Replace er i rekkefølge. Gå til: Rediger> Finn i prosjekt. Med det nye vinduet legger du inn Event som finn og Lap som erstatning. Fjern merket for "Ignore Case" som vi bare vil hente på den strenge kapitaliseringen av funnet. Endre deretter rullegardinmenyen der "Inneholder" er valgt, og velg "Hele ord" i stedet. Dette vil begrense finner ned til nøyaktig hva vi trenger.

Klikk finn. Se gjennom endringene. Hvis alt har gått bra, så utfør erstatningen!

Endre det aktive skjemaet

Så vi har opprettet en ny versjon av skjemaet, gjort noen modifikasjoner, og nå er det på tide å få søknaden inn i det nye skjemaet.

Ingenting vanskelig her. Velg det nye skjemaet du vil angi som aktivt, og naviger til: Design> Datamodell> Angi gjeldende versjon. Det grønne krysset vil flytte til det nye skjemaet, og det er alt klart å gå.

Bygg og kjør programmet. Alt skal være bra, og søknaden skal åpne, migrere og kjøre. Du vil ikke merke denne overføringen i det hele tatt, ikke engang en feilsøkingsutgang. Men det faktum at koden kjører og jobber, er bevis på at den har migrert.

oppsummering

Så programmet har nå et endret enhetnavn. Dette kan skje fra tid til annen i utviklingen av enhver applikasjon. Du kan legge til nye egenskaper med denne lette overføringsmetoden med samme prosess.

Hvis du trenger å endre typen av en eiendom eller gjøre mer avanserte endringer, må du dykke inn i Mapping Model Object-migrasjon. Dette er en mer avansert metode for hva vi utførte, og krever ekstra konfigurasjoner og kode. Apple iOS-dokumentasjonen har en veldig god gjennomgang av denne avanserte migreringsprosessen.