2009-10-06 15 views
9

Stworzyłem aplikację narzędziową, która jest prawie kompletna, ale teraz jestem na punkcie, że naprawdę muszę utrzymywać dane.Jak dodać dane podstawowe do istniejącej aplikacji narzędziowej

Ponieważ XCode dostarcza tylko podstawowe szablony danych w aplikacji nawigacyjnej lub opartej na oknach, czy istnieje prosty sposób dodawania podstawowych danych do mojej aplikacji? Nigdy nie pracowałem z Core Data i po prostu musiałem utrzymywać komunikaty z 460 postaciami i nazwą kontaktu jako historią wysyłanych wiadomości.

Czy powinienem zacząć od nowej aplikacji opartej na systemie Window Based Application? Core Data i spróbuj ręcznie zbudować część Utility/Flipside?

Czy ktoś może zaproponować mi najlepszą praktykę w mojej sytuacji?

Odpowiedz

9

Musisz dodać strukturę CoreData do swojego celu, utworzyć model danych i utworzyć instancję obiektów NSManagedObjectModel, NSPersistentStoreCoordinator i .

Dodawanie danych Core do istniejącej aplikacji jest pokrótce omówione this Apple document (wyszukaj „istniejącej aplikacji”)

Należy również zobaczyć Apple tutorial aby zorientować się, co jest zaangażowana.

Zawsze można rozważyć użycie tylko SQLite.

+2

zgadzam się z ideą przy użyciu SQLite zamiast. Core Data jest dość ciężkim zadaniem i ponieważ wygląda na to, że nie ma tu zbyt wielu danych ani skomplikowanych relacji, SQLite może być mniej złożonym, bardziej wydajnym sposobem na zrobienie tego. –

+3

Podstawowe dane są łatwiejsze, gdy zrozumiesz, jak to działa - jest to szczególnie ważne w przypadku małych projektów. –

+4

Głosowałbym za odrzuceniem własnego kodu bezpośrednio przeciwko SQLite. Cały taki kod, jaki kiedykolwiek widziałem, ponownie zaimplementował części danych podstawowych, ale w sposób błędny i jeszcze mniej korzystny. Core Data to sposób, szczególnie, gdy wiązania są dodawane do Cocoa Touch na drodze. – PeyloW

6

Utwórz nowy projekt w XCode, korzystając z dostarczonych szablonów - znajdź taki, który ma pole do sprawdzenia, czy dane podstawowe są przechowywane.

To daje plik xcdatamodel i niektóre zmienne kodu/klasy w delegacie aplikacji, które można skopiować z tego projektu do bieżącego.

Gorąco polecam samouczek firmy Apple wspomniany przez nall.

Jeśli zdecydujesz się użyć zamiast tego bezpośrednio SQLLite, zdecydowanie rozważ użycie opcji FMDB, która upraszcza kod SQL. To jeden plik dodawany do projektu.

+0

Bardzo polecam także FMDB, jeśli zamierzasz używać SQLite. –

18

Ponieważ staram się również zrozumieć twighlightzone z podstawowych danych, wymyśliłem następujące kroki, aby przenieść "normalny" projekt do podstawowych danych (poprzez porównanie pustego projektu aplikacji z pustym projektem aplikacji z danymi podstawowymi)

Krok 1: Dodaj CoreData.framework

a) W "Podsumowanie projektu celowego" pod "Linked Frameworks i Bibliotek" dodaj CoreData.framework pomocą przycisku +
b) Wybierz Plik/Nowy/Plik, a następnie w sekcji "Dane podstawowe" dodaj nowy "Model danych" (i nazwij go, np. XXXXXXX (dla nazewnictwa patrz 3.b)
c) W pliku APPLIKATION-Prefiks. PCH (gdzie STOSOWANIE to nazwa projektu) dodać

#import <CoreData/CoreData.h> 

ramach dwóch pozostałych obejmują dyrektyw

Krok 2: W AppDelegate.H dodać następujące właściwości:/metody zgłoszenia

@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext; 
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel; 
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator; 

- (void)saveContext; 
- (NSURL *)applicationDocumentsDirectory; 

Krok 3: AppDelegate.m

a) Syntesize właściwości:

@synthesize managedObjectContext = __managedObjectContext; 
@synthesize managedObjectModel = __managedObjectModel; 
@synthesize persistentStoreCoordinator = __persistentStoreCoordinator; 

b) na koniec modułu dodaj następujące linie:

Ważne: W Methode managedObjectModel i persistentStoreCoordinator trzeba wymienić XXXXXXX witka nazwę akt osobowych .xcdatamodeld

- (void)saveContext 
{ 
    NSError *error = nil; 
    NSManagedObjectContext *managedObjectContext = self.managedObjectContext; 
    if (managedObjectContext != nil) 
    { 
     if ([managedObjectContext hasChanges] & ![managedObjectContext save:&error]) 
     { 
      /* 
      Replace this implementation with code to handle the error appropriately. 

      abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 
      */ 
      NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
      abort(); 
     } 
    } 
} 

#pragma mark - Core Data stack 

/** 
Returns the managed object context for the application. 
If the context doesn't already exist, it is created and bound to the persistent store coordinator for the application. 
*/ 
- (NSManagedObjectContext *)managedObjectContext 
{ 
    if (__managedObjectContext != nil) 
    { 
     return __managedObjectContext; 
    } 

    NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; 
    if (coordinator != nil) 
    { 
     __managedObjectContext = [[NSManagedObjectContext alloc] init]; 
     [__managedObjectContext setPersistentStoreCoordinator:coordinator]; 
    } 
    return __managedObjectContext; 
} 

/** 
Returns the managed object model for the application. 
If the model doesn't already exist, it is created from the application's model. 
*/ 
- (NSManagedObjectModel *)managedObjectModel 
{ 
    if (__managedObjectModel != nil) 
    { 
     return __managedObjectModel; 
    } 
    NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"XXXXXXX" withExtension:@"momd"]; 
    __managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; 
    return __managedObjectModel; 
} 

/** 
Returns the persistent store coordinator for the application. 
If the coordinator doesn't already exist, it is created and the application's store added to it. 
*/ 
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator 
{ 
    if (__persistentStoreCoordinator != nil) 
    { 
     return __persistentStoreCoordinator; 
    } 

    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"XXXXXXX.sqlite"]; 

    NSError *error = nil; 
    __persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; 
    if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) 
    { 
     /* 
     Replace this implementation with code to handle the error appropriately. 

     abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 

     Typical reasons for an error here include: 
     * The persistent store is not accessible; 
     * The schema for the persistent store is incompatible with current managed object model. 
     Check the error message to determine what the actual problem was. 


     If the persistent store is not accessible, there is typically something wrong with the file path. Often, a file URL is pointing into the application's resources directory instead of a writeable directory. 

     If you encounter schema incompatibility errors during development, you can reduce their frequency by: 
     * Simply deleting the existing store: 
     [[NSFileManager defaultManager] removeItemAtURL:storeURL error:nil] 

     * Performing automatic lightweight migration by passing the following dictionary as the options parameter: 
     [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil]; 

     Lightweight migration will only work for a limited set of schema changes; consult "Core Data Model Versioning and Data Migration Programming Guide" for details. 

     */ 
     NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
     abort(); 
    }  

    return __persistentStoreCoordinator; 
} 

#pragma mark - Application's Documents directory 

/** 
Returns the URL to the application's Documents directory. 
*/ 
- (NSURL *)applicationDocumentsDirectory 
{ 
    return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; 
} 
+0

, w jaki sposób zarządzany kontekst byłby świadomy modelu? automatycznie? – fengd

+0

@ Jun1st: zmiana nazwy plików sqlite i momd na takie same, jak w xcdatamodel, to w jaki sposób ten przykład łączy kontekst z modelem – ColdLogic

Powiązane problemy