I am having our app move it's readonly db to the App Support directory so that content updates can update it as well(over the wire updates, not app updates). The code below is in the app delegate to copy over the db, however on the first run NSFileManager in following attempts(during that run) to see if it is there or to load it does not see the copied file. However, it is copying it because if I close the app and restart it, everything works fine. I'm at a lose.
NSFileManager *fm = [[[NSFileManager alloc] init] autorelease];
NSError *err = nil;
NSURL *ASD = [fm URLForDirectory:NSApplicationSupportDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:&err];
if (!err) {
NSURL* path = [NSURL URLWithString:DATABASE_NAME relativeToURL:ASD];
NSString *bundle = [[ NSBundle mainBundle] pathForResource:@"datafiles/data_main" ofType:@"sqlite"];
if ([fm fileExistsAtPath:[path path]]) {
if([DatabaseManager isBundledDBNewerThenInUse]){
NSLog(@"bundled db is newer");
[DatabaseManager close];
[fm removeItemAtURL:path error:&err];
if (err) {
NSLog(@"Error deleting old DB:%@",err);
}
else {
[fm copyItemAtPath:bundle toPath:[path path] error:&err];
if (err) {
NSLog(@"Error in copying over DB:%@",err);
}
else
{
NSLog(@"db should have been copied over correctly");
}
}
}
}
else{
[fm copyItemAtPath:bundle toPath:[path path] error:&err];
if (err) {
NSLog(@"Error in copying over DB:%@",err);
}
}
}
else
{
NSLog(@"Error in opening AS for DB copy:%@",err);
}
"[DatabaseManager isBundledDBNewerThenInUse]" returns YES if the db in the App Support directory either isn't there or has a version that is older then the one in the bundle. It opens the db in the App Support directory thus the [DatabaseManager close] before trying to remove it. I'm using FMDB in my DatabaseManager if that helps at all. But as I said after that initial load if you kill the app and go back into it it work perfectly. (On a database update from bundle you the db isn't updated on that first load either.) Any help would be great and if you need more info please just ask! Thanks!
The answer was dispatch_async on the main thread and then double checking the cached data and reloading it if needed. Corrected code:
dispatch_async(dispatch_get_main_queue(),^(){
NSFileManager *fm = [[[NSFileManager alloc] init] autorelease];
NSError *err = nil;
NSURL *ASD = [fm URLForDirectory:NSApplicationSupportDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:YES error:&err];
if (!err) {
NSURL* path = [NSURL URLWithString:DATABASE_NAME relativeToURL:ASD];
NSString *bundle = [[ NSBundle mainBundle] pathForResource:@"datafiles/data_main" ofType:@"sqlite"];
if ([fm fileExistsAtPath:[path path]]) {
if([DatabaseManager isBundledDBNewerThenInUse]){
NSLog(@"bundled db is newer");
[DatabaseManager close];
[fm removeItemAtURL:path error:&err];
if (err) {
NSLog(@"Error deleting old DB:%@",err);
}
else {
[fm copyItemAtPath:bundle toPath:[path path] error:&err];
if (err) {
NSLog(@"Error in copying over DB:%@",err);
}
else
{
NSLog(@"db should have been copied over correctly");
}
}
}
}
else{
[fm copyItemAtPath:bundle toPath:[path path] error:&err];
if (err) {
NSLog(@"Error in copying over DB:%@",err);
}
else
NSLog(@"DB Copied");
}
}
else
{
NSLog(@"Error in opening AS for DB copy:%@",err);
}
});