4

I always used this solution when I needed to parse a feed JSON.

https://stackoverflow.com/a/20077594/2829111

But sendAsynchronousRequest is now deprecated and I'm stuck with this code

__block NSDictionary *json;    
[[session dataTaskWithURL:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        // handle response
        json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
        NSLog(@"Async JSON: %@", json);
        [collectionView reloadData];
}] resume];

And with this the reloadData argument takes a long time to execute. I've alredy tried forcing back to the main queue with:

__block NSDictionary *json;    
[[session dataTaskWithURL:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
            // handle response
            json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
            NSLog(@"Async JSON: %@", json);
            dispatch_sync(dispatch_queue_create("com.foo.samplequeue", NULL), ^{[collectionView reloadData});
}] resume];
Community
  • 1
  • 1
  • you should try this lib, very awesome https://github.com/icanzilb/JSONModel – Cong Tran Dec 15 '15 at 05:12
  • 1
    bring the whole request part into different thread and run, then only reload table in main thread – Tj3n Dec 15 '15 at 05:17
  • 1
    Usually you don't need to use dispatch_sync , instead use dispatch_async even if it's on the main queue ! In your case you should use dispatch_async on the main queue to reload data with dispatch_async and on dispatch_get_main_queue() – Oleg Sherman Dec 15 '15 at 05:40
  • Common Class for WS Calling http://stackoverflow.com/questions/33767908/volunteermatch-api-objective-c/33886449#33886449 – Vvk Dec 15 '15 at 05:48

3 Answers3

1

The problem is that the completion handler does not run on the main queue. But all UI updates must happen on the main queue. So dispatch that to the main queue:

[[session dataTaskWithURL:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    // handle response
    NSError *parseError;
    NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
    // do something with `json`
    dispatch_async(dispatch_get_main_queue()), ^{[collectionView reloadData]});
}] resume];
Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • Needless to say, I'd check that `error` and `parseError` were both `nil`, otherwise log that message so you can diagnose the problem. And of course, you don't need `__block` variable (just define it within the closure), but you do need to update whatever model structure the collectionView uses. But I'm assuming you just omitted all of that for the sake of brevity in your question. The real issue is that you should dispatch UI updates to the main queue. (And you might as well dispatch it asynchronously.) – Rob Dec 15 '15 at 05:44
0

Why don't you try JSONModel library....... it is so simple to use

-(void)getEmployeePerformance:(EmpPerformanceRequest*)request
              withSuccesBlock:(succesEmployeePerformanceResponseBlock) successBlock
                 andFailBlock:(FailResponseBlock) failBlock
{       
    NSString* weatherUrl    = [[ABWebServiceUtil sharedInstance]getEmployeePerformanceURL];
    [HTTPClientUtil postDataToWS:weatherUrl parameters:[request toDictionary] WithHeaderDict:nil withBlock:^(AFHTTPRequestOperation *responseObj, NSError *error)
     {

        if(responseObj.response.statusCode == HTTP_RESPONSE_SUCESS)
        {
            EmpPerformanceArrayModel *empPerfArrModel;
           if(responseObj.responseString)
           {
               empPerfArrModel                  = [[EmpPerformanceArrayModel alloc]initWithString:result error:nil];
               empPerfArrModel.employeesArray   = [empPerformanceModel arrayOfModelsFromDictionaries:empPerfArrModel.employeesArray];
           }
            if(successBlock)
            {
                successBlock(responseObj.response.statusCode, empPerfArrModel);
            }
        }else if (failBlock)
        {
            failBlock(responseObj.response.statusCode);
        }
     }];
}

for more detail follow this link...... it will brief you well

https://github.com/icanzilb/JSONModel

Ashutosh Maurya
  • 341
  • 1
  • 6
-1

Try parsing JSON in connectionDidFinishLoading so you will get response as NSDictionary.

-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
Class NSJSONSerializationclass = NSClassFromString(@"NSJSONSerialization");
    NSDictionary *result;
    NSError *error;

    if (NSJSONSerializationclass)
    {
        result = [NSJSONSerialization JSONObjectWithData: responseData options: NSJSONReadingMutableContainers error: &error];
    }

    // If the webservice response having values we have to call the completionBlock…
    if (result)
    {
        if (self.completionBlock != nil)
        {
            self.completionBlock(result);
        }
    }
}
Arun
  • 85
  • 1
  • 1
  • 8
  • He's not using `NSURLConnection` (nor should he, because it's now deprecated). In fact, that was the premise of the question, as he's replaced the `NSURLConnection` method, `sendAsynchronousRequest`, with the corresponding `NSURLSession` method. If he wanted to stay with `NSURLConnection`, he would have just kept `sendAsynchronousRequest`. – Rob Dec 15 '15 at 06:00