6

Core Data ベースの iOS アプリケーションを使用している一部のお客様から、データが失われることがあると報告されています。報告は非常に奇妙です。そのため、これについての見解をお聞きしたいと思います。顧客は、しばらくしてから (数分、数時間、または翌日) アプリケーションを再度開くと、基礎となるデータベースが以前の状態に戻ったかのように一部のデータが失われると報告しています。

私は数年間 Core Data を扱ってきましたが、これまでこのような問題に遭遇したことはありません。アプリケーションは非常に単純です。つまり、1 つの管理対象オブジェクト コンテキストのみを使用し、アプリケーションがバックグラウンドに移行する前に変更がコミットされます。

これは見込みのないことだと思いますが、この種の問題の潜在的な原因は何か、またはより多くの情報を収集するためにどのようなチェックを行うことができますか? 残念ながら、この問題を自分で再現することはできません。

アップデート:

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
    if (_persistentStoreCoordinator) return _persistentStoreCoordinator;

    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Prime.sqlite"];

    NSError *error = nil;
    _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];

    if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:@{ NSMigratePersistentStoresAutomaticallyOption : @YES, NSInferMappingModelAutomaticallyOption : @YES } error:&error]) {
        // Error Handling
    }

    return _persistentStoreCoordinator;
}
4

3 に答える 3

2

保存せずにアプリケーションを辞任する方法がないように、適切な appDelegate メソッドに保存メッセージを入れたかどうかを確認してください。applicationWillResignActive と applicationWillTerminate は、すべてのニーズをカバーする必要があります。

その適切なエラー処理とロギングは別として、多くの根拠が得られるはずです。個人的には、これらのタイプのエラーをファイルに記録して、要求に応じて送信できるようにしたいと思っています。しかし、それはあなたの特定のアプリケーションにとってはやり過ぎかもしれません。記憶で書いていますので、多少の誤差はご容赦ください。

NSError *error = nil;
if (![[self managedObjectContext] save:&error])
{
    NSString *errorString = @"%@ ERROR : %@ %@", [[NSDate date] description], [error localizedDescription], [error userInfo]);

    NSString *documentsDirectory = [NSHomeDirectory() 
                                    stringByAppendingPathComponent:@"Documents"];

    NSString *filePath = [documentsDirectory 
                          stringByAppendingPathComponent:@"errorLog.txt"];

    // Write to the file
    [errorString writeToFile:filePath atomically:YES 
            encoding:NSUTF8StringEncoding error:&error];
}
于 2013-06-03T14:58:37.400 に答える
1

メソッドがエラーを報告するかどうかを確認する必要がありsave:ます。たとえば、次のようになります。

NSError *error = nil;
if (![[self managedObjectContext] save:&error])
{
    NSLog(@"Error %@", action, [error localizedDescription]);    
    NSArray* detailedErrors = [[error userInfo] objectForKey:NSDetailedErrorsKey];
    // if there is a detailed errors - we can dump all of them
    if(detailedErrors != nil && [detailedErrors count] > 0) {
        for(NSError* detailedError in detailedErrors) {
            NSLog(@"  DetailedError: %@", [detailedError localizedDescription]);
        }
    }
    else { // in other case lets dump all the info we have about the error
        NSLog(@"  %@", [error userInfo]);
    }
}

最も一般的な失敗の理由の 1 つは、検証エラーです。たとえば、ユーザーが入力していないフィールドが表示されると予想される場合や、値が XX 文字未満であると予想される場合などです。

つまり、クライアントにデバッグ情報を含む新しいビルドを提供するのに時間がかかりすぎる場合は、クライアントが入力に使用するデータの例を送信するように依頼できます。

于 2013-06-02T13:57:30.740 に答える
1

これが理由かどうかはわかりませんが、アプリがバックグラウンドに移行したときに、何らかの理由でこれを処理するための最大許容時間 (backgroundTimeRemaining) を超えている可能性があります。アップルのドキュメントから:

このプロパティには、アプリケーションがシステムによって強制終了される前にバックグラウンドで実行する必要がある時間が含まれます。アプリケーションがフォアグラウンドで実行されている間、このプロパティの値は適切な大きさのままです。アプリケーションが beginBackgroundTaskWithExpirationHandler: メソッドを使用して 1 つ以上の実行時間の長いタスクを開始し、その後バックグラウンドに移行する場合、このプロパティの値は、アプリケーションの残りの実行時間を反映するように調整されます。

コンテキストの保存に時間がかかりすぎるためにアプリが強制終了された場合、Core Data は、少なくとも一貫性を保つために以前の状態を復元することを決定する場合があります。この問題を報告している一部のユーザーからログ結果を取得できる場合は、コンテキストを保存しようとした後にプロパティ値をログに記録して、これを確認できます。

于 2013-06-03T13:48:37.220 に答える