Efter att ha läst Första stegen med Core Data, befinner vi oss upplysta i hur Core Data fungerar och hur det kan hjälpa oss att utveckla datarika applikationer. Ytan skreds dock bara bara, och i vissa applikationer kan du sluta undra hur man implementerar en viss funktion.
Under de senaste månaderna har jag arbetat med Core Data på ett husdjursprojekt. Det är en applikation att dra in data från ett fjärrservice API, lagra data i Core Data, och visa det i en samling av UITableViews. Under utvecklingens gång har den gått från en databasbaserad databutik (* shudder *) till en Core Data SQL-butik. Efter tre fullständiga ombyggnader och många långa nätter av felsökning har min ansökan äntligen blivit ett snabbt, kraschfritt och minnesläckagefritt projekt. För mig har Core Data gjort min ansökan vad den var avsedd att vara, och jag kommer att dela mycket av det jag har lärt mig med dig i denna och framtida artiklar.
För den här artikeln kommer vi att bygga på den tidigare applikationen LapTimer och visa att man utför lättviktiga migreringar.
När du utvecklar en applikation får du nästan aldrig schemat rätt första gången. Så, Core Data har stöd för schemaläggning och data migrering. Det här låter dig definiera en ny version av Core Data-schemat genom att lägga till ett nytt attribut eller en enhet i affären. Definiera sedan hur butiken måste migrera från en ändring till en annan.
Core Data hanterar schemanversioner annorlunda än några andra ramar som du kanske har använt tidigare. När du går igenom utveckling och kräver ett nytt attribut eller enhet är processen att lägga till dessa genom att skapa en ny xcdatamodel-fil för din ansökan. Den här nya filen kommer att versioneras, ha ett inkrementellt nummer i filnamnet och skiljer sig från äldre schemanversioner. I LapTimer-programmet skapar du den nya datamodellversionen. Klicka på xcdatamodel-filen i din ansökan och navigera sedan till menyalternativet på: Design> Data Model> Lägg till modellversion.
Du kommer nu ha ett xcdatamodel-träd, föräldern är en ny xcdatamodel-fil, med en ny schemaversion betecknad med inkrementalnumret. Det finns också en grön tick mot det gamla schemat. Detta indikerar vilket schema som är aktivt och det program som ska användas. Det är viktigt att notera att val av den nya versionen direkt kan orsaka vissa problem i utvecklingen. Eftersom vi inte har installerat en migrering för det här nya schemat än, om vi skulle göra det nya schemat det aktiva, kommer simulatorn eller enheten att fel och krascha vid start. Som en demonstration, ta en titt på felet nedan, det är vanligt för vad människor stöter på vid första försöket:
Det säger i princip bara "Hej, du ändrade det aktiva DB-schemat och jag fastnar på en äldre version." Detta förhindrar applikationen från konflikter och fel med Core Data Store-schemat ändras. Det gör en jämförelse baserat på detaljerna i schemat som butiken arbetar med. Om det har fått en ny schemaversion att använda men det matchar inte vad det har installerats eller migrerats till, så får du det här felet.
Så, hur får vi förbi detta? Tja, det finns två alternativ:
Detta är en enkel att använda och en automatisk funktion av Core Data, men det är begränsat till bara enkla migreringar, varför anledningen är lätt. Du kan bara använda den här metoden om ändringarna är bland följande:
Obs! Innan vi dyker in, om du arbetar med LapTimer-projektet måste du bygga projektet innan vi börjar. Se till att den aktiva xcdatamodellen är den första versionen som programmet byggdes med. På så sätt kan du se migreringsarbetet.
Som en demonstration kommer programvaran LapTimer att få Event-enheten ändrad till Lap. Med detta måste vi också uppdatera Event.h och Event.m klasserna och eventuella händelser av dem i applikationen. Med ett par fina Xcode-funktioner är det smärtfritt.
Så, i den nya versionen av xcdatamodellen som vi skapade tidigare, kommer jag att göra förändringen genom att helt enkelt ändra värdena i enhetens detaljeringspanel. Nu måste vi ange "Renaming Identifier" till Event. Så i samma panel klickar du på skiftnyckeln / skiftnyckel och skriver in "Event" i fältet Renaming Identifier, som så:
Nästa steg är att berätta Core Data att den kan utföra lätta migreringar vid start. Hänvisar till LapTimer-programmet, i filen LapTimerAppDelegate.m måste vi lägga till en kod till - (NSPersistentStoreCoordinator *) persistentStoreCoordinator-metoden:
- (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]; om (! [persistentStoreCoordinator addPersistentStoreWithType: NSSQLiteStoreType konfiguration: noll URL: storeUrl alternativ: alternativfel: & error]) / * Ersätt denna implementering med kod för att hantera felet på lämpligt sätt. Avbryt () orsakar att applikationen genererar en kraschlogg och avslutar. Du bör inte använda denna funktion i en fraktansökan, även om den kan vara användbar under utveckling. Om det inte går att återställa felet, visar en varningspanel som instruerar användaren att avsluta programmet genom att trycka på Hem-knappen. Typiska orsaker till ett fel här är: * Den ihållande butiken är inte tillgänglig * Schemat för den ihållande butiken är inkompatibel med den aktuella hanterade objektmodellen Kontrollera felmeddelandet för att bestämma vad det aktuella problemet var. * / NSLog (@ "Oövat fel% @,% @", fel, [fel userInfo]); avbryta(); returnera persistentStoreCoordinator;
Koden som lagts till var alternativen NSDictionary som kommer att berätta Core Data för att utföra automatiska migreringar.
Vi är nästan färdiga. Nästa steg är att ändra klassfilerna för händelseföretaget för att återspegla det nya namnet. För att göra detta använder vi min favoritfunktion för Xcode, Refactor-funktionen. Som underförstått av namnet, kommer denna funktion att refactor och göra en mer avancerad Sök & Ersätt på ditt projekt för situationer som dessa.
För att göra detta måste du öppna Event.m och välj texten "Event" på den filen. Gå sedan till: Redigera> Refactor (Cmd + Shift + J). Upp kommer pop ett fönster med alternativ och fält som skärmdumpen nedan. Skriv in ordet Lap i fältet "Event till". Klicka förhandsgranskning och du får resultatet av alla ändringar:
Om du vill koll på vad det här ska göra klickar du på en av filerna i resultatpanelen och det visar dig detaljer om vad det kommer att förändras. Det kommer även att omdöpa Event.h och Event.m-filerna för oss. Bara att notera, tidigare xcdatamodel-filer med den särskilda NSManagedObject-klassen som byts ut kommer att ha en liten förändring. Det kommer att ändra enhetens klassnamn, inte dess enhetens namn, så om en enhet måste gå igenom migrering kan den fortfarande använda enheterna NSManagedObject-klass och relaterade metoder.
Hit gäller. Det är allt. Som en säkerhetsåtgärd kommer det också att ta en ögonblicksbild, en annan stor egenskap hos XCode. Så om allt går fel kan du bara gå tillbaka till föregående ögonblicksbild, precis som Time Machine men minus alla stjärnor och Swirly Galaxy UI.
Tyvärr fångar inte alla ändringar som behövs. Det finns fortfarande några bitar i programmet LapTimer som refererar till händelsen. Så en snabb Find & Replace är i ordning. Gå till: Redigera> Sök i projekt. Med det nya fönstret ange Event som hitta och Lap som ersätt. Avmarkera "Ignorera fallet" eftersom vi bara vill hämta den strikta bokstaven i sökningen. Ändra sedan rullgardinsmenyn där "Innehåller" väljs och välj "Hela ord" istället. Detta kommer att begränsa finden till exakt vad vi behöver.
Klicka på Sök. Granska ändringarna. Om allt har gått bra, utför sedan bytet!
Så vi har skapat en ny version av schemat, gjort några ändringar, och nu är det dags att få ansökan till det nya schemat.
Inget knepigt här. Välj det nya schema du vill ställa in som aktiv och navigera till: Design> Data Model> Ställ aktuell version. Den gröna kryssrutan kommer att flytta till det nya schemat och det är klart att gå.
Bygg och kör programmet. Allt borde vara bra och applikationen bör öppnas, migrera och springa. Du kommer inte att märka denna migrering alls, inte ens en debugger-utgång. Men det faktum att koden körs och fungerar är ett bevis på att det har migrerat.
Så ansökan har nu ett ändrat företagsnamn. Detta kan hända då och då i utvecklingen av någon applikation. Du kan lägga till nya egenskaper med denna lätta migreringsmetod med samma process.
Om du behöver byta typ av egenskap eller göra mer avancerade ändringar måste du dyka in i mappmodellobjekt. Detta är en mer avancerad metod för vad vi utförde, vilket kräver extra konfigurationer och kod. Apple iOS-dokumentationen har en riktigt bra genomgång av denna avancerade migrationsprocess.