简体   繁体   中英

Updating managed object in background thread

When a new item is added in my app, it also saves on the server. This save happens in a separate thread in the background due to latency over the internet.

However, once the insert is complete, I want to grab the server insert_id and save it for that item in Core Data back on the handheld. Because of latency, I assume this has to happen in the background thread as well and the time of the save will be unpredictable.

From Googling, it seems that that the right way to do this is to create a new managed object context on the background thread and locate the record to update using NSPredicate .

Is this correct?

If so, can anyone point me toward code or a tutorial that would show how to do it.

Would like to find shortcut to full blown search for new item such as following as I'm not sure of best way to find it:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSManagedObjectContext *context = [IDModel sharedInstance].managedObjectContext; //IS THIS A NEW CONTEXT IN SECOND THREAD
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"id IN %@", uids];//I don't know what id is...
fetchRequest.predicate = predicate;
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Item" inManagedObjectContext:context];
NSFetchedResultsController *fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:context sectionNameKeyPath:nil cacheName:nil];                
NSError *error = nil;

if (![fetchedResultsController performFetch:&error]) {
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
}

NSArray *fetchedObjects = fetchedResultsController.fetchedObjects;
NSInteger resultCount = [fetchedObjects count];

if (resultCount == 0) {
    NSLog(@"THERE ARE NO ITEMS WITH IDS IN CORE DATA STORE");
    return [NSMutableDictionary dictionary];//nothing in the Core Data store
} else {
    Items *item;

Would appreciate any suggestions.

I wouldn't do the Core Data saving part in a background thread, this is just a PHP/MySQL insert ID which is probably around 10 bytes and won't take longer than 50ms.

But for posting or getting data from the internet I would say you need to do that in an async request on background thread and when you received a response, save it to Core Data immediately on the main thread.

// show loading indicators when you are fetching data
[[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES];

[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
    // hide loading indicators when you received a response
    [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO];

    if (connectionError) {
        // Handle error
    } else {
        NSDictionary *jsonResults = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
        NSLog(@"jsonResults: %@", jsonResults);

        // reload views or insert to core data on main thread
        dispatch_async(dispatch_get_main_queue(), ^{
            [self.myCollectionView reloadData]; // example
            [self insertDataIntoDatabase:jsonResults]; // example
        });
    }
}];

I would also advise looking into a shared instance for your Core Data if you are gonna use it a lot all over your app.

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