Jakiś sposób na zapełnienie podstawowych danych?

Tworzyłem aplikację listy i wspierałem ją podstawowymi danymi.

Chciałbym mieć domyślną listę powiedzmy 10 pozycji airport, aby użytkownik nie musiał zaczynać od zera.

Czy Jest jakiś sposób, aby to zrobić?

Każda pomoc jest mile widziana. Z góry dzięki.

Author: Irfan, 2010-02-09

9 answers

Oto najlepszy sposób (i nie wymaga znajomości SQL):
Utwórz aplikację quick Core Data iPhone (lub nawet Mac app) przy użyciu tego samego modelu obiektu, co aplikacja listy. Napisz kilka linii kodu, aby zapisać domyślne zarządzane obiekty, które chcesz zapisać do sklepu. Następnie uruchom aplikację w symulatorze. Teraz przejdź do ~ / Library / Application Support / iPhone Simulator/User / Applications. Znajdź swoją aplikację wśród identyfikatorów GUID, a następnie po prostu skopiuj sklep SQLite do folderu projektu aplikacji listy.

Then, załaduj ten sklep tak, jak to robią w przykładzie CoreDataBooks.

 57
Author: Ken Aspeslagh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-10 02:20:29

Tak jest w rzeczywistości przykład CoreDataBooks robi to, możesz pobrać kod tutaj: przykładowy kod

To, co robisz, to tworzenie wewnętrznego sklepu (bazy danych) za pomocą zwykłej procedury inicjalizacji sklepu, tak jak w przypadku każdego innego sklepu, a następnie po prostu uruchamiasz kod i pozwalasz mu wykonać kod zgodnie z opisem w przykładzie CoreDataBooks (fragment kodu poniżej). Po zainicjowaniu sklepu będziesz chciał utworzyć NSManagedObjectContext i zainicjować go za pomocą utworzono trwały sklep, wstawiono wszystkie potrzebne elementy i zapisano kontekst.

Po pomyślnym zapisaniu kontekstu możesz zatrzymać swoją aplikację, następnie przejść do Findera i przejść do folderu: ~/Library/Developer wpisz w wyszukiwarce .sqlite i szukać pod / Developer, sortowanie według daty daje najnowsze .baza danych sqlite, która powinna pasować do czasu wykonania kodu, możesz następnie wziąć ten sklep i dodać go jako zasób swojego projektu. Plik ten można następnie odczytać za pomocą stały koordynator sklepu.

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {

if (persistentStoreCoordinator) {
    return persistentStoreCoordinator;
}


NSString *storePath = [[self applicationDocumentsDirectory]      stringByAppendingPathComponent: @"CoreDataBooks.sqlite"];
 /*
  Set up the store.
 For the sake of illustration, provide a pre-populated default store.
 */
NSFileManager *fileManager = [NSFileManager defaultManager];
// If the expected store doesn't exist, copy the default store.
if (![fileManager fileExistsAtPath:storePath]) {
  NSString *defaultStorePath = [[NSBundle mainBundle] pathForResource:@"CoreDataBooks"      ofType:@"sqlite"];
 if (defaultStorePath) {
 [fileManager copyItemAtPath:defaultStorePath toPath:storePath error:NULL];
 }
}

NSURL *storeUrl = [NSURL fileURLWithPath:storePath];

 NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:[NSNumber   numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil]; 
  persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];

 NSError *error;
 if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {
  // Update to handle the error appropriately.
  NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
 exit(-1);  // Fail
}    

return persistentStoreCoordinator;
}
Mam nadzieję, że to pomoże.

-Oscar

 29
Author: Oscar Gomez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-28 14:37:31

dzięki tej metodzie nie musisz tworzyć osobnej aplikacji ani mieć żadnej wiedzy SQL. Musisz tylko mieć możliwość utworzenia pliku JSON dla początkowych danych.

Używam pliku JSON, który analizuję do obiektów, a następnie wstawiam je do podstawowych danych. Robię to, gdy aplikacja inicjalizuje. Robię również jeden element w moich danych podstawowych, który wskazuje, czy te początkowe dane są już wstawione, po wstawieniu danych początkowych ustawiam ten element, więc następnym razem, gdy skrypt uruchomi, widzi, że początkowe dane została już zainicjowana.

Aby wczytać plik json do obiektów:

NSString *initialDataFile = [[NSBundle mainBundle] pathForResource:@"InitialData" ofType:@"json"];
NSError *readJsonError = nil;
NSArray *initialData = [NSJSONSerialization
                        JSONObjectWithData:[NSData dataWithContentsOfFile:initialDataFile]
                        options:kNilOptions
                        error:&readJsonError];

if(!initialData) {
    NSLog(@"Could not read JSON file: %@", readJsonError);
    abort();
}

Następnie możesz tworzyć dla niego obiekty encji w następujący sposób:

[initialData enumerateObjectsUsingBlock:^(id objData, NSUInteger idx, BOOL *stop) {

    MyEntityObject *obj = [NSEntityDescription
                          insertNewObjectForEntityForName:@"MyEntity"
                          inManagedObjectContext:dataController.managedObjectContext];

    obj.name = [objData objectForKey:@"name"];
    obj.description = [objData objectForKey:@"description"];

    // then insert 'obj' into Core Data

}];

Jeśli chcesz uzyskać bardziej szczegółowy opis, jak to zrobić, sprawdź ten samouczek: http://www.raywenderlich.com/12170/core-data-tutorial-how-to-preloadimport-existing-data-updated

 11
Author: gitaarik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-07-05 08:30:03

Dla 10 elementów, można to zrobić w applicationDidFinishLaunching: w aplikacji delegat.

Zdefiniuj metodę, na przykład insertPredefinedObjects, która tworzy instancje jednostki odpowiedzialnej za zarządzanie elementami airport i zapełnia je, a także zapisuje kontekst. Możesz albo odczytać atrybuty z pliku, albo po prostu podłączyć je do swojego kodu. Następnie wywołaj tę metodę wewnątrz applicationDidFinishLaunching:.

 8
Author: Massimo Cafaro,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-24 23:23:18

Pamiętaj, że postępując zgodnie z przykładowym kodem CoreDataBooks, prawdopodobnie łamie on wytyczne dotyczące przechowywania danych w systemie iOS:

Https://developer.apple.com/icloud/documentation/data-storage/

Aplikacja została odrzucona do skopiowania wstępnie wypełnionej bazy danych (tylko do odczytu) do katalogu documents - ponieważ następnie zostaje ona zarchiwizowana do iCloud - a Apple chce, aby stało się to tylko z plikami generowanymi przez użytkowników.

Powyższe wytyczne oferują pewne rozwiązania, ale w większości do:

  • Przechowuj DB w katalogu pamięci podręcznej i z wdziękiem radź sobie z sytuacjami, w których system operacyjny oczyszcza pamięć podręczną - będziesz musiał odbudować DB, co prawdopodobnie wyklucza to dla większości z nas.

  • Ustaw atrybut "nie buforuj" na pliku DB, co jest trochę tajemnicze, ponieważ musi być zrobione inaczej dla różnych wersji systemu operacyjnego.

Nie sądzę, że jest to zbyt trudne, ale pamiętaj, że masz trochę więcej do zrobienia, aby ten przykładowy kod pracuj razem z iCloud...

 5
Author: Adrian Bigland,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-19 11:05:28

Więc opracowałem ogólną metodę, która ładuje się ze słownika (prawdopodobnie z JSON) i wypełnia bazę danych. Powinien być używany tylko z zaufanymi danymi (z bezpiecznego kanału), nie może obsługiwać odniesień kołowych i migracje schematów mogą być problematyczne... Ale dla prostych przypadków użycia, takich jak mój, powinno być dobrze

Here it goes

- (void)populateDBWithDict:(NSDictionary*)dict
               withContext:(NSManagedObjectContext*)context
{
    for (NSString* entitieName in dict) {

        for (NSDictionary* objDict in dict[entitieName]) {

            NSManagedObject* obj = [NSEntityDescription insertNewObjectForEntityForName:entitieName inManagedObjectContext:context];
            for (NSString* fieldName in objDict) {

                NSString* attName, *relatedClass, *relatedClassKey;

                if ([fieldName rangeOfString:@">"].location == NSNotFound) {
                    //Normal attribute
                    attName = fieldName; relatedClass=nil; relatedClassKey=nil;
                } else {
                    NSArray* strComponents = [fieldName componentsSeparatedByString:@">"];
                    attName = (NSString*)strComponents[0];
                    relatedClass = (NSString*)strComponents[1];
                    relatedClassKey = (NSString*)strComponents[2];
                }
                SEL selector = NSSelectorFromString([NSString stringWithFormat:@"set%@:", attName ]);
                NSMethodSignature* signature = [obj methodSignatureForSelector:selector];
                NSInvocation* invocation = [NSInvocation invocationWithMethodSignature:signature];
                [invocation setTarget:obj];
                [invocation setSelector:selector];

                //Lets set the argument
                if (relatedClass) {
                    //It is a relationship
                    //Fetch the object
                    NSFetchRequest* query = [NSFetchRequest fetchRequestWithEntityName:relatedClass];
                    query.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:relatedClassKey ascending:YES]];
                    query.predicate = [NSPredicate predicateWithFormat:@"%K = %@", relatedClassKey, objDict[fieldName]];

                    NSError* error = nil;
                    NSArray* matches = [context executeFetchRequest:query error:&error];


                    if ([matches count] == 1) {
                        NSManagedObject* relatedObject = [matches lastObject];
                        [invocation setArgument:&relatedObject atIndex:2];
                    } else {
                        NSLog(@"Error! %@ = %@ (count: %d)", relatedClassKey,objDict[fieldName],[matches count]);
                    }


                } else if ([objDict[fieldName] isKindOfClass:[NSString class]]) {

                    //It is NSString
                    NSString* argument = objDict[fieldName];
                    [invocation setArgument:&argument atIndex:2];
                } else if ([objDict[fieldName] isKindOfClass:[NSNumber class]]) {

                    //It is NSNumber, get the type
                    NSNumber* argument = objDict[fieldName];
                    [invocation setArgument:&argument atIndex:2];

                }
                [invocation invoke];


            }

            NSError *error;
            if (![context save:&error]) {
                NSLog(@"%@",[error description]);
            }
        }
    }   
}

I ładunki z json...

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"initialDB" ofType:@"json"];
NSData *jsonData = [NSData dataWithContentsOfFile:filePath];

NSError* error;
NSDictionary *initialDBDict = [NSJSONSerialization JSONObjectWithData:jsonData
                                                           options:NSJSONReadingMutableContainers error:&error];

[ self populateDBWithDict:initialDBDict withContext: [self managedObjectContext]];

Przykłady JSON

    {
    "EntitieA": [ {"Att1": 1 }, {"Att1": 2} ],
    "EntitieB": [ {"Easy":"AS ABC", "Aref>EntitieA>Att1": 1} ]
    }

I

{
    "Country": [{"Code": 55, "Name": "Brasil","Acronym": "BR"}],
    "Region": [{"Country>Country>code": 55, "Code": 11, "Name": "Sao Paulo"},
               {"Country>Country>code": 55, "Code": 31, "Name": "Belo Horizonte"}]
}
 2
Author: Felizardo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-31 20:51:12

Może sprawdzisz, czy istnieją jakieś obiekty, a jeśli nie, utwórz je z danymi?

NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Settings"];
_managedObjectSettings = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];

if ([_managedObjectSettings count] == 0) {
    // first time, create some defaults
    NSManagedObject *newDevice = [NSEntityDescription insertNewObjectForEntityForName:@"Settings" inManagedObjectContext:managedObjectContext];

    [newDevice setValue:[NSNumber numberWithBool: YES ] forKey:@"speed"];
    [newDevice setValue:[NSNumber numberWithBool: YES ] forKey:@"sound"];
    [newDevice setValue:[NSNumber numberWithBool: NO ] forKey:@"aspect"];
    [newDevice setValue:[NSNumber numberWithBool: NO  ] forKey: @"useH264"];
    [newDevice setValue:[NSNumber numberWithBool: NO ] forKey: @"useThumbnail"];

    NSError *error = nil;
    // Save the object to persistent store
    if (![managedObjectContext save:&error]) {
        NSLog(@"Can't Save! %@ %@", error, [error localizedDescription]);
    }
}
 2
Author: Md1079,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-14 12:01:02

Ta odpowiedź jest tylko dla osób, które są

  • w tym wstępnie wypełnionej bazy danych w aplikacji
  • tworzenie aplikacji na wiele platform (iOS, Android, itp.)

Zrobiłem wstępnie wypełnioną bazę danych SQLite dla aplikacji na Androida. Kiedy tworzyłem wersję aplikacji na iOS, pomyślałem, że najlepiej będzie użyć Core Data. Spędziłem więc dość dużo czasu ucząc się podstawowych danych, a następnie przepisując kod, aby wstępnie wypełnić bazę danych. Nauka wykonywania każdego kroku w obie platformy wymagały wielu badań i prób i błędów. Było o wiele mniej nakładania się, niż bym się spodziewał.

W końcu zdecydowałem się użyć tej samej bazy danych SQLite z mojego projektu Android. Następnie użyłem wrappera FMDB, aby uzyskać bezpośredni dostęp do bazy danych w systemie iOS. Korzyści:

  • wystarczy tylko raz utworzyć wstępnie wypełnioną bazę danych.
  • Nie wymaga zmiany paradygmatu. Składnia między Androidem a FMDB, choć inna, jest nadal dość podobna.
  • mieć dużo więcej kontroli nad tym, jak zapytania są wykonywane.
  • umożliwia wyszukiwanie pełnotekstowe.

Chociaż nie żałuję uczenia się podstawowych danych, gdybym miał zrobić to ponad mogłem zaoszczędzić dużo czasu, po prostu trzymając się SQLite.

Jeśli zaczynasz w systemie iOS, a następnie planujesz przenieść się na Androida, nadal używałbym wrappera SQLite, takiego jak FMDB lub innego oprogramowania, aby wstępnie wypełnić bazę danych. Chociaż możesz technicznie wyodrębnić bazę danych SQLite, którą wstępnie wypełniasz podstawowymi danymi, schemat (nazwy tabel i kolumn, itp.) będzie dziwnie nazwany.

Przy okazji, jeśli nie musisz modyfikować wstępnie wypełnionej bazy danych, nie kopiuj jej do katalogu documents po zainstalowaniu aplikacji. Po prostu uzyskaj do niego dostęp bezpośrednio z pakietu.

// get url reference to databaseName.sqlite in the bundle
let databaseURL: NSURL = NSBundle.mainBundle().URLForResource("databaseName", withExtension: "sqlite")!

// convert the url to a path so that FMDB can use it
let database = FMDatabase(path: databaseURL.path)
To sprawia, że nie masz dwóch kopii.

Update

Używam teraz SQLite.swift zamiast FMDB, ponieważ lepiej integruje się z projektami Swift.

 2
Author: Suragch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-08-26 01:48:24

Inną metodą przechowywania wartości domyślnych jest NSUserDefaults. niespodzianka!) I to proste.

Sugerowane przez niektórych, umieścić to w applicationDidFinishLaunching

W podanym przypadku 10 defaults, Airport0 thru 9

Ustawienie

NSUserDefaults *nud = [NSUserDefaults standardUserDefaults];
[nud setString:@"MACADDRESSORWHY" forKey:@"Airport0"];
    ...
[nud setString:@"MACADDRESSORWHY" forKey:@"Airport9"];
[nud synchronize];

Lub

[[NSUserDefaults standardUserDefaults] setString:@"MACADDRESSORWHY" forKey:@"Airport9"]];
     ...
[[NSUserDefaults standardUserDefaults] synchronize];

A następnie, uzyskanie domyślnych.

NSString *air0 = [[NSUserDefaults standardUserDefaults] stringForKey:@"Airport0"];
 0
Author: Gabe Rainbow,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-03-25 04:00:02