2011-11-17 5 views
0

私たちのアプリをReadonlyデータベースに移動させているので、コンテンツのアップデートでもアップデートが可能です(アプリのアップデートではありません)。以下のコードは、アプリケーションデリゲートがdbをコピーすることですが、最初の実行時にNSFileManagerを実行して(実行中に)そこにあるかどうかを確認したり、コピーしたファイルがロードされていないかどうかを確認します。しかし、私はそれをコピーしているので、私はアプリを終了し、それを再起動すると、すべて正常に動作します。私は失っている。アプリのサポートディレクトリ内のDBが存在しないか、またはバンドル内の1その後、古いバージョンを持っているいずれかの場合iOS NSFileManagerはコピーしますが、次の負荷までファイルが応答しません

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]は」YESを返します。 App Supportディレクトリのdbを開き、削除する前に[DatabaseManager close]を開きます。私はDatabaseManagerでFMDBを使用しています。しかし、最初の負荷の後、アプリを終了して元の状態に戻すと、完全に機能します。 (バンドルからのデータベース更新では、dbはその最初の読み込み時に更新されません)。どんな助けも素晴らしいでしょう。ありがとう!

答えて

0

答えはメインスレッドでdispatch_asyncでした。その後、キャッシュされたデータを再度チェックし、必要に応じて再読み込みしました。修正されたコード:

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); 
    } 
}); 
0

あなたが説明した(つまり、アプリケーションを再起動すると、コピーされたデータベースが見つかります)、どこかの重要なデータベースのオープン/クローズコールが不足しているように聞こえます。

私は、データベースの呼び出しをどこで行うかを二重に確認し、それが意味をなさないことを確認します。データベースオープンコールがありませんか?上記のコードでデータベースオープンコールがある場合、コピーが発生した後、データベースがアプリバンドルからアプリサポートディレクトリにコピーされる場合は、

+0

オープンとクローズの機能にいくつかのログを記録し、それらが呼び出されていないことが分かった。 "fileExistsAtPath:"テストはそれまでにも失敗する前に失敗しています。だから...素晴らしい考え(私は実際に自分自身を持っていた)が、私は恐れている。 :(他のアイデアは? –

関連する問題