简体   繁体   中英

iOS RestKit + Core Data. Fetching slow and Core Data error

I am using Restkit and Core Data to fetch and store data from a Web Service. I have two problems. The first one is that the fetch of 3200 records takes around 10 seconds. I guess it shouldn't be so slow. Here is my code:

- (void)fetchDataFromRemote{

    RKManagedObjectMapping *coursesMapping = [RKManagedObjectMapping mappingForClass:[Course class] inManagedObjectStore:[[RKObjectManager sharedManager] objectStore]];
    [coursesMapping mapKeyPathsToAttributes:@"code", @"code",@"name",@"name", nil];
    //Set the primary key. Records in this way are not duplicated when fetched
    coursesMapping.primaryKeyAttribute = @"code";
    [[[RKObjectManager sharedManager] mappingProvider] setMapping:coursesMapping forKeyPath:@"course"];

    RKManagedObjectMapping *cacheMapping = [RKManagedObjectMapping mappingForClass:[Cache class] inManagedObjectStore:[[RKObjectManager sharedManager] objectStore]];
    [cacheMapping mapKeyPathsToAttributes:@"updated",@"updated",@"expires",@"expires", nil];
    //Set the primary key. Records in this way are not duplicated when fetched
    cacheMapping.primaryKeyAttribute = @"expires";

    [coursesMapping mapRelationship:@"cache" withMapping:cacheMapping];
    [[[RKObjectManager sharedManager] mappingProvider] setMapping:cacheMapping forKeyPath:@"cache"];

    RKURL *URL = [RKURL URLWithBaseURL:[[RKObjectManager sharedManager] baseURL] resourcePath:@"/course/-" queryParameters:nil];

    [[RKObjectManager sharedManager] loadObjectsAtResourcePath:[NSString stringWithFormat:@"%@", [URL resourcePath]] delegate:self];
    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
    NSLog(@"Start:%@",[NSDate date]);
}

And here when I receive the response from the server:

- (void)objectLoader:(RKObjectLoader *)objectLoader didLoadObjects:(NSArray *)objects
{

    NSLog(@"End:%@",[NSDate date]);
    //Dismiss the activity indicator
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;

    NSLog(@"objects[%d]", [objects count]);

    self.coursesArray = objects;

    //Initialize the filtered array
    self.filteredCoursesArray = [[NSMutableArray alloc] initWithCapacity:[self.coursesArray count]];

    [self.tableView reloadData];

}

I guess it's not that different from the tutorial I found on the web.

The second problem instead is related to the aforementioned method fetchDataFromRemote: When I add this bunch of lines:

RKManagedObjectMapping *cacheMapping = [RKManagedObjectMapping mappingForClass:[Cache class] inManagedObjectStore:[[RKObjectManager sharedManager] objectStore]];
        [cacheMapping mapKeyPathsToAttributes:@"updated",@"updated",@"expires",@"expires", nil];
        //Set the primary key. Records in this way are not duplicated when fetched
        cacheMapping.primaryKeyAttribute = @"expires";

        [coursesMapping mapRelationship:@"cache" withMapping:cacheMapping];
        [[[RKObjectManager sharedManager] mappingProvider] setMapping:cacheMapping forKeyPath:@"cache"];

I got an exception in the tableview:cellForRowAtIndexPath: because it seems that the object is not anymore a 'Course' object but is a 'Cache' object so sending a message to a selector that 'Cache' object doesn't know makes the app crash. If I remove the lines before everything is ok but I need to set that relationship. I'm not sure I've done everything ok, I'm a newbie of Core Data.

Any help would be really appreciated! Thanks

Your methods are looking good for me. A duration of 10 seconds for 3200 objects seems quite slow but depends on your mapping and the relationships.

If you want to check for any errors during import, you can 1) enable the SQL output in your scheme or 2) log all output that RestKit provides to determine errors in import, that will slow down the progress.

1) -com.apple.CoreData.SQLDebug 1 // Add in "Arguments" Tab > "Arguments Passed On Launch"
2) RKLogConfigureByName("RestKit/*", RKLogLevelTrace); // Add to AppDelegate

The problem is with your code itself. You initialize the filtered array with some count but never added objects to it. This would be solved if you replace the method as;

- (void)objectLoader:(RKObjectLoader *)objectLoader didLoadObjects:(NSArray *)objects
{

    NSLog(@"End:%@",[NSDate date]);
    //Dismiss the activity indicator
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;

    NSLog(@"objects[%d]", [objects count]);

    self.coursesArray = objects;

    //Initialize the filtered array
    self.filteredCoursesArray = [[NSMutableArray alloc] initWithobjects:objects];

    [self.tableView reloadData];
`]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM