2

最初の実行時に、バックエンド サービス (StackMob ですが、ここではサービスの選択は重要ではないと思います) から大量のデータをダウンロードし、それを plist ファイルにキャッシュし、. plist を Core-Data ストアに格納します。その後の実行では、同じクラスを使用して新しいデータまたは更新されたデータを取得し、Core-Data ストアに同期します。Apple の Core-Data スタックの代わりに MagicalRecord を使用しています。インポート/同期は NSOperationQueue で実行されます。

そのキューは、8 つのエンティティのそれぞれに対して 1 つのメソッドを実行し、それらのメソッドの 1 つが次のようになります...

- (void)processAppData
{
    NSString *entityName = kEntityAppData;                                          // customise for entity
    NSString *smidName = kAttribute_appdata_id;                                     // customise for entity
    NSArray *syncData = [MFGlobals cachedDataForName:entityName];
    [[NSFileManager defaultManager] removeItemAtPath:[MFGlobals cachePathForDownloadNamed:entityName]
                                               error:nil];
    if (!syncData) return;

    NSLog(@"%@ items: %i", entityName, [syncData count]);
    NSNumber *lastUpdated = [MFGlobals lastUpdatedEntityNamed:entityName];
    NSLog(@"Last updated %@: %qu", entityName, [lastUpdated unsignedLongLongValue]);

    for (NSDictionary *item in syncData) {
        AppData *object;                                                            // customise for entity
        NSString *smid = [item objectForKey:smidName];
        NSNumber *lastmoddate = [item objectForKey:kAttribute_lastmoddate];
        NSLog(@"%@ item with ID: %@ lastmoddate: %qu", entityName, smid, [lastmoddate unsignedLongLongValue]);

        object = [self dataItemFromEntity:entityName withID:smid inField:smidName];

        if (!object) {
            // we have to create a new item
            object = [NSEntityDescription insertNewObjectForEntityForName:entityName
                                                   inManagedObjectContext:localContext];
            [object setAppdata_id:smid];                                            // customise for entity
        } else {
            // we have an item that _might_ need updating
            if ([object lastmoddate] >= lastmoddate)
                continue;
        }

        [object setLastmoddate:lastmoddate];
        [object setValue:[item objectForKey:kAttribute_value]];
        NSLog(@"new/updated %@ object: %@", entityName, [object description]);

        [localContext saveNestedContexts];
        NSLog(@"%@ object updated.", entityName);

        if ([lastmoddate compare:lastUpdated] == NSOrderedDescending)
            lastUpdated = lastmoddate;
    }

    [MFGlobals setLastUpdated:lastUpdated forEntityNamed:entityName];
    NSLog(@"New last updated %@: %qu", entityName, [lastUpdated unsignedLongLongValue]);
}

[localContext save]プロセスの代わりに使用すると[localContext saveNestedContexts]、正しく実行されているように見えます。データはいつ、どのように UI に表示され、アプリ内を移動できますが、データは sqlite データベースに保持されません。

ここからヒントを得てMagicalRecord -- saveinBackground はデータを保持していませんか? [localContext saveNestedContexts]最初の 6 つのエンティティのデータを正しく処理して保持するようになりました。ただし、次のエンティティの最初のレコードでは、そのレコードが正しく保存され、アプリがロック状態になります。アプリを再度実行すると、そのエンティティの次の (事実上最初の新しい) レコードで同じことが起こります。そのエンティティにすべてのデータがあると、次の (& 最後のエンティティ) の最初の (& 現在のみ) レコードでも同じことが起こります。

NSManagedObjectContextここで説明したアプローチは、コンテキストで MagicalRecord が提供する & MagicalRecord 保存メソッドを使用していることを除いて、Apple スタイルの Core-Data コードで使用して成功したものと基本的に同じです。

また、MagicalRecord saveInBackgroundWithBlock(キューを使用しない) を使用してこれを実行しようとしましたが、すべてのエンティティで最初のレコードの問題でロックが発生しました。

これを適切に機能させる方法についての手がかりはありますか?

乾杯 & TIA、ペドロ

4

0 に答える 0