尝试将Web服务数据与本地存储同步时,逻辑上缺少某些内容,需要您的帮助。 这就是我得到的:

我有一个NSDictionaries NSArray描述每个事件对象(从Web下载),我按事件ID对其进行排序。 然后,我使用IN谓词获取本地存储,并按事件ID对其进行排序。 然后,我尝试迭代并匹配id,如果它们匹配,则更新记录,如果它们不匹配,则创建新的NSManagedObject 如果新下载的事件对象的eventID比本地存储区中的上一个eventID大,则工作正常,但是如果Web服务中的eventID小于本地存储区中的eventID ,则它插入所有对象 ,无论它们是否存在,并且正是我的问题。

因此,换句话说,如果新记录位于已排序数组的开头,它将添加每个对象,但是如果它位于已排序数组的末尾,则它将更新除新记录之外的所有对象。 我需要它来创建新的并更新旧的。

这是一些代码:

我认为我缺少某些东西的逻辑函数:

- (void)findOrCreateObject:(NSArray*)eventArray
{
    NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];

    //get sorted stored records
    NSArray *fetchedRecords = [self.fetchedResultsController fetchedObjects];

    //sort dictionaries
    NSSortDescriptor *aSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"id" ascending:YES];
    NSArray *downloadedRecords = [self.events sortedArrayUsingDescriptors:[NSArray arrayWithObject:aSortDescriptor]];

    NSLog(@"DOWNLOADED EVENTS = %@", downloadedRecords);

    NSLog(@"FETCHED EVENTS = %@", fetchedRecords);


    //if store is not empty we need to walk through data and add/update records, otherwise/ELSE we need to import initial data
    if (fetchedRecords.count != 0) {
        //stores has records already
        NSLog(@"FIND OR CREATE PROCESS");

        if ([downloadedRecords count] > 0) {

            NSArray *storedRecords = [self fetchEvents:eventArray withContext:context];

            NSUInteger currentIndex = 0;
            for (NSDictionary* event in downloadedRecords) {
                Event* eventObject = nil;

                if ([storedRecords count] > currentIndex) {

                    eventObject = [storedRecords objectAtIndex:currentIndex];
                }

                NSLog(@"STRING VALUE OF KEY = %@", [[eventObject valueForKey:@"eventID"]stringValue]);

                if ([[event valueForKey:@"id"] isEqualToString:[[eventObject valueForKey:@"eventID"] stringValue]]) {

                    //Update Record
                    NSLog(@"Updating Record!!!");
                    [self updateManagedObject:eventObject withRecord:event inContext:context];

                }
                else
                {
                    //New Record
                    NSLog(@"Inserting Record!!!");
                    eventObject = (Event*)[NSEntityDescription insertNewObjectForEntityForName:@"Event" inManagedObjectContext:context];
                    eventObject.eventID = [self makeNumberFromString:[event valueForKey:@"id"]];
                    eventObject.title = [event valueForKey:@"title"];
                    eventObject.venue = [event valueForKey:@"venue"];

                }
                 currentIndex++;
            }

        }

    }
    else
    {

        //import initial data
        NSLog(@"IMPORTING INITIAL DATA");

        for (NSDictionary* event in downloadedRecords) {

            Event *eventObject = (Event*)[NSEntityDescription insertNewObjectForEntityForName:@"Event" inManagedObjectContext:context];

            eventObject.eventID = [self makeNumberFromString:[event valueForKey:@"id"]];
            eventObject.title = [event valueForKey:@"title"];
            eventObject.venue = [event valueForKey:@"venue"];

        }
    }


    // Save the context.
    NSError *error = nil;
    if (![context save:&error]) {

        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    }
}

FETCHEVENTS方法:

-(NSArray*)fetchEvents:(NSArray*)eIDs withContext:(NSManagedObjectContext*)context
{

    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Event" inManagedObjectContext:context];
    [fetchRequest setEntity:entity];

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(eventID IN %@)", eIDs];
    [fetchRequest setPredicate:predicate];

    [fetchRequest setSortDescriptors:@[ [[NSSortDescriptor alloc] initWithKey: @"eventID" ascending:YES] ]];

    NSError *error = nil;
    NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
    if (fetchedObjects == nil) {
        NSLog(@"No rows returned");
    }

    return fetchedObjects;
}

更新对象方法:

- (void)updateManagedObject:(NSManagedObject*)object withRecord:(NSDictionary*)record inContext:(NSManagedObjectContext*)context
{
    [object setValue:[self makeNumberFromString:[record valueForKey:@"id"]] forKey:@"eventID"];
    [object setValue:[record valueForKey:@"title"] forKey:@"title"];
    [object setValue:[record valueForKey:@"venue"] forKey:@"venue"];
}

下载Web服务数据并解析后,我将调用findOrCreate方法。

如果您还有其他问题,请告诉我。

===============>>#1 票数:1 已采纳

尝试这个,

- (void)findOrCreateObject:(NSArray*)eventArray {

//if store is not empty we need to walk through data and add/update records, otherwise/ELSE we need to import initial data
    if (fetchedRecords.count != 0) {
        //stores has records already
        NSLog(@"FIND OR CREATE PROCESS");

        if ([downloadedRecords count] > 0) {

            NSArray *storedRecords = [self fetchEvents:eventArray withContext:context];
            for (NSDictionary* event in downloadedRecords) {
                NSPredicate *predicate = [NSPredicate predicateWithFormat:@"eventID = %@",[event valueForKey:@"id"]];
                NSArray *matchedArray = [storedRecords filteredArrayUsing
Predicate:predicate]; 
                Event* eventObject = nil;
                if ([matchedArray count] > 0) {

                    //Update Record
                    NSLog(@"Updating Record!!!");
                    eventObject = [matchedArray objectAtIndex:0];
                    [self updateManagedObject:eventObject withRecord:event inContext:context];

                }
                else
                {
                    //New Record
                    NSLog(@"Inserting Record!!!");
                    eventObject = (Event*)[NSEntityDescription insertNewObjectForEntityForName:@"Event" inManagedObjectContext:context];
                    eventObject.eventID = [self makeNumberFromString:[event valueForKey:@"id"]];
                    eventObject.title = [event valueForKey:@"title"];
                    eventObject.venue = [event valueForKey:@"venue"];

                }
            }
        }
    } else {
        .....
    }
}

===============>>#2 票数:0

我认为,每次插入新的事件对象时,都应更新storedObjects ,使其现在应包含插入的对象。 或者更简单地说,你应该把的初始化行storedObjects你在for循环中。 (这将确保当您从downloadedObjects开头枚举时,每个eventObject都将具有与storedObjects上相同的索引。但是,对于您的代码,只有在总是在downloadedObjects找到storedObjects所有元素的情况下, storedObjects是正确的我认为是这种情况。)

但是,有一件事不是fetchedRecords应该与storedObjects相同,如果是,则应将storedObjects重新分配为[self.fetchedResultsController fetchedObjects] ,因为它可以反映上下文中的更改,而无需执行另一个解决请求的方法以上建议的效率低下。

  ask by SasaT translate from so

未解决问题?本站智能推荐: