1

I'm currently doing this when populating core data from a JSON file:

NSString *urlString = [value objectForKey:@"url"];
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSURLResponse *response = nil;
NSError *error = nil;
NSData *dataResponse = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
[managedObject setValue:dataResponse forKey:@"image"];

Is there a better (asynchronous) way to do this with AFNetworking? What is the best method for this case? Does it have to be synchronous because we're dealing with CoreData?

UPDATE: Trying this now:

NSOperationQueue *queue = [[NSOperationQueue alloc] init];

[NSURLConnection sendAsynchronousRequest:request queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
                 {
                     [managedObject setValue:data forKey:@"image"];
                 }];

For some reason when I access the managed object later, the image attribute is always null, even though *data above is not null in the completion handler. The image gets saved fine in the synchronous method. What am I missing?

soleil
  • 12,133
  • 33
  • 112
  • 183
  • 2
    add an 'a' letter in front of the `synchronous` part of the method name... –  Sep 07 '12 at 17:43
  • @H2CO3 concise and good comment +1 – Lorenzo B Sep 07 '12 at 17:51
  • I think you need to do a `save` on the context. But pay attention to threads. Accessing `NSManagedObject` and `NSManagedObjectContext` from different threads like you do is error prone. To avoid this instead of passing a new queue, use `[NSOperationQueue mainQueue]` for `NSURLConnection`. – Lorenzo B Sep 07 '12 at 19:16
  • The download will complete async while the save of data will be complete on main thread. In addition I would pay attention when you save images in core data. This is a simple rule of thumb: http://stackoverflow.com/questions/2090028/core-data-storing-images-iphone/2098401#2098401. – Lorenzo B Sep 07 '12 at 19:20
  • When you save data you could notice a freeze on the app if the image you download is big. If the image is small, the delay could be negligible. – Lorenzo B Sep 07 '12 at 19:22
  • the data still doesn't persist using the async method even if I do a context save. – soleil Sep 07 '12 at 19:39

2 Answers2

0

NSURLConnection can deal with async too.

The method that you can use is (iOS >= 5) is

+ sendAsynchronousRequest:queue:completionHandler:

If you need to target iOS < 5 then use the delegate pattern for NSURLConnection. A good wrapper for this can be found in NSURLConnection and grand central dispatch.

About Core Data, I would say it depends. If data you need to store is cheap, do it in the main thread. On the contrary you have three different ways to do it:

  • (1) use new Core Data queue-based API (iOS >= 5)
  • (2) kick off a NSOperation within a NSOperationQueue and do the long work in background
  • (3) use GDC

Pay attention to Core Data constraints (threads constraints) when you deal with (2) or (3).

Hope that helps.

P.S. If you want to know something else let me know.

Community
  • 1
  • 1
Lorenzo B
  • 33,216
  • 24
  • 116
  • 190
0

There's a sendAsynchronousRequest:queue:completionHandler: message of NSURLConnection.