Pre-Populating Core Data with plist on applications first launch only
Asked Answered
D

2

5

I have a plist file which is an array of dictionaries. Where each dictionary contains a set of strings. Each dictionary represents a celebrity.

What I would like to do is populate Core Data with the contents of this plist on the applications first launch, after which I would like to somehow check core data for the existence of my data, and if there is data, load it from there, otherwise load the initial data from the plist file again.

I know its possible to populate core data from a plist, but is what I'm suggesting a viable solution? Or is there a better approach?

Jack

Discouragement answered 25/3, 2012 at 16:57 Comment(0)
T
8

My sample code

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

if (![defaults objectForKey:@"dataImported"]) {

    NSString *path = [[NSBundle mainBundle] pathForResource:@"dict" ofType:@"plist"];
    NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:path];
    for (NSString *key in [dict allKeys]) {
        NSDictionary *node = [dict objectForKey:key];

        MyClass *newObj = .....
    }

   [defaults setObject:@"OK" forKey:@"dataImported"];
   [defaults synchronize];
}
Transaction answered 25/3, 2012 at 17:14 Comment(1)
Shouldn't it be NSDictionary *node = [dict objectForKey:key]? Otherwise, I think you will get a warning about key not being recognized selector for NSDictionary.Worth
T
0

This is doing the same thing but with a slightly more complex pList that contains an array of dictionaries representing data on a "topic" to be stored. It still has some of the debug logging in place. Hope it is useful to someone.

NSManagedObjectContext *context = self.managedObjectContext;
NSError *error;

NSFetchRequest *topicRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *topicEntityDescription = [NSEntityDescription entityForName:@"Topic" inManagedObjectContext:context];
[topicRequest setEntity:topicEntityDescription];
NSManagedObject *newTopic = nil;
NSArray *topics = [context executeFetchRequest:topicRequest error:&error];
if (error) NSLog(@"Error encountered in executing topic fetch request: %@", error);

if ([topics count] == 0)  // No topics in database so we proceed to populate the database
{
    NSString *topicsPath = [[NSBundle mainBundle] pathForResource:@"topicsData" ofType:@"plist"];
    NSArray *topicsDataArray = [[NSArray alloc] initWithContentsOfFile:topicsPath];
    int numberOfTopics = [topicsDataArray count];

    for (int i = 0; i<numberOfTopics; i++)
    {
        NSDictionary *topicDataDictionary = [topicsDataArray objectAtIndex:i];
        newTopic = [NSEntityDescription insertNewObjectForEntityForName:@"Topic" inManagedObjectContext:context];
        [newTopic setValuesForKeysWithDictionary:topicDataDictionary];
        [context save:&error];
        if (error) NSLog(@"Error encountered in saving topic entity, %d, %@, Hint: check that the structure of the pList matches Core Data: %@",i, newTopic, error);
    };
}
Trilley answered 17/1, 2013 at 9:25 Comment(2)
One question; should I replace NSManagedObject *newTopic... for my NSManagedObject subclass name? One more thing, you run that executeFetchRequest on line 8 to get topics array just to be able to test if its 0? Cause if you test for first run, it should be zero, right? I have come up with this github gist where I posted the resulting dataset from the server and the code Im writing: gist.github.com/quique123/5126202Corium
Sorry for the very long delay! I did not notice I had an inbox in StackOverflow. Yes - sole purpose of that request is to test. Mostly the data is there so the system passes by and delivers content to the user.Trilley

© 2022 - 2024 — McMap. All rights reserved.