How to get data to return from NSURLSessionDataTask

I have a registration view controller that processes all user input and calls a function in another class (wsClass) passed to it, this data as NSDictionary.

A function is called in wsClass and a connection is made, and data is returned from the server and available in the session.

My question is how to return this data to the control registration controller, where the function was originally called, it always becomes empty.

Here is the call in registrationViewController:

wsClass *ws = [[wsClass alloc] init]; NSDictionary *testDict = [[NSDictionary alloc] initWithObjectsAndKeys:username.text,@"username",email.text,@"email",password.text,@"password", nil]; NSDictionary *respDict = [ws sendData:testDict]; 

Here is the function called in wsClass.m:

 - (NSDictionary *)sendData:(NSDictionary *)sendDict { NSMutableString *sendStr = [[NSMutableString alloc] init]; [sendDict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { [sendStr appendFormat:@"&%@=%@", key, obj]; }]; NSLog(@"sendStr is: %@",sendStr); NSString *noteDataString = [NSString stringWithFormat:@"%@%@",REQUIRED,sendStr]; NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration]; NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlTest]]; request.HTTPBody = [noteDataString dataUsingEncoding:NSUTF8StringEncoding]; request.HTTPMethod = @"POST"; NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { // The server answers with an error because it doesn't receive the params // handle response if(error == nil) { [getReqAlert dismissWithClickedButtonIndex:0 animated:YES]; NSError *e = nil; jsonArray = [NSJSONSerialization JSONObjectWithData: data options: NSJSONReadingMutableLeaves error: &e]; if (!jsonArray) { NSLog(@"Error parsing JSON: %@", e); } else { NSLog(@"resp: %@ = %@",[jsonArray objectForKey:@"status"],[jsonArray objectForKey:@"msg"]); NSLog(@"Dictionary count: %lu", jsonArray.count); } } }]; [postDataTask resume]; return jsonArray; 

}

+6
source share
4 answers

The message ends asynchronously, so your wsClass should inform the caller of completion after recording is completed. A good way to do this is to increase the sendData method with a block of code provided by the caller, which should be launched upon completion:

Change sendData: so:

 // it doesn't return anything, because all it does is launch the post // but when the post is done, it invokes completion - (void)sendData:(NSDictionary *)sendDict completion:(void (^)(NSDictionary *))completion { // the stuff you're already doing NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { // the stuff you're already doing // now tell the caller that you're done completion(jsonArray); }]; } 

Now the caller looks like this:

 // change the UI to say "I'm busy doing the post" [ws sendData:testDict completion:^(NSDictionary *responseDict) { NSLog(@"this runs later, after the post completes %@", responseDict); // change the UI to say "The post is done" }]; 

Just a few notes about this: (1) I did not add an error parameter to the block, you probably should. Check this and call the block with zero and error or with json and error = nil output. (2) Your code assumes that the json result is parsed as a dictionary. Be sure to always be correct before accepting it in code. (3) Class names usually begin with caps.

+14
source

It might work.

  • Add nsDictVariable interface variable for NSDict or whatever you retrieve in class
  • In SendData, assign it: self.nsDictVariable = ....
0
source

Try it. This will work well.

 -(void)loadDetails { NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]]; [[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { _allVehicleLocationsArray = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; [self afterCompleteDoThis]; }] resume]; } -(void)afterCompleteDoThis{ for (NSDictionary *vehicleDict in _allVehicleLocationsArray) { NSLog(@" PPP %@" , [vehicleDict valueForKey:@"vehicleType"]); } } 
0
source

You can use Semaphores for wiating until the block completes execution and then returns a value from the function

 - (NSDictionary *)sendData:(NSDictionary *)sendDict { NSMutableString *sendStr = [[NSMutableString alloc] init]; [sendDict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { [sendStr appendFormat:@"&%@=%@", key, obj]; }]; NSLog(@"sendStr is: %@",sendStr); NSString *noteDataString = [NSString stringWithFormat:@"%@%@",REQUIRED,sendStr]; NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration]; NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfiguration]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlTest]]; request.HTTPBody = [noteDataString dataUsingEncoding:NSUTF8StringEncoding]; request.HTTPMethod = @"POST"; let semaphore = dispatch_semaphore_create(0) NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { // The server answers with an error because it doesn't receive the params // handle response if(error == nil) { [getReqAlert dismissWithClickedButtonIndex:0 animated:YES]; NSError *e = nil; jsonArray = [NSJSONSerialization JSONObjectWithData: data options: NSJSONReadingMutableLeaves error: &e]; if (!jsonArray) { NSLog(@"Error parsing JSON: %@", e); } else { NSLog(@"resp: %@ = %@",[jsonArray objectForKey:@"status"],[jsonArray objectForKey:@"msg"]); NSLog(@"Dictionary count: %lu", jsonArray.count); dispatch_semaphore_signal(semaphore) } } }]; [postDataTask resume]; dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER) return jsonArray; 

}

0
source

All Articles