Nikita Pestrov
Nikita Pestrov

Reputation: 5966

Core Data and 10 000 audio files

I have an entity "Word", and the are two properties in it - inputSound and outputSound,both of them are little,about 10KB audio files, but there would be 4000 instances od this entity in my SQL database.

First, i tried to store them as a binary data in my SQL, and it made it work quite slow. So then i found an option to "Store in External Record File" and i want to ask,if this would help me,or i should better just store url to the audio file in my entity property?

If first is better, how should i move my pesistent store from Bundle to documents directory at the first launch?

Right now i'm just coping an SQL(it's prepopulated by me in the developer's part of my app),but how should i do that with so many files?And can i do that in backgrouns somehow to make my first launch faster and more user-friendly?

This is how i do it now

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{

if (__persistentStoreCoordinator != nil)
        return __persistentStoreCoordinator;

NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                         [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
                         [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)lastObject];
NSString *defaultStore = [documentsDirectory stringByAppendingPathComponent:@"Easy10.sqlite"];

NSString *sqliteInBundle = [[[NSBundle mainBundle] pathForResource:@"Easy10" ofType:@"sqlite"]stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Easy10.sqlite"]; 
NSError *error =nil;
NSFileManager *fileManager = [NSFileManager defaultManager];

if (![fileManager fileExistsAtPath:defaultStore])
    [fileManager copyItemAtPath:sqliteInBundle toPath:defaultStore error:&error];



__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
[__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error];    
return __persistentStoreCoordinator;

}

Upvotes: 1

Views: 1302

Answers (1)

Scott Corscadden
Scott Corscadden

Reputation: 2860

For binary (and especially large ones, though your case of "many" of them can also apply) the recommended method seems to be to use Core Data to store the metadata, including a file path to the actual binary itself. Thus you'd store these things somewhere in the Application's sandbox (i.e., perhaps a subdirectory of your creation in the "Documents" directory). Then you can use the [NSData dataWithContentsOfFilePath] or similar to actually get the bytes when you want to play them, but your Core Data fetches aren't slowed down by trying to shovel those bytes around.

Definitely take a look at the WWDC video on optimizing Core Data. Great examples of how to use Instruments and additional "SQL Debug Timing" switches to make sure that what you're optimizing… actually got optimized. :)

Upvotes: 2

Related Questions