I have a registration view controller which handles all the user input and calls a function in another class (wsClass) passing to it, that data as an NSDictionary.
T
This might work.
The post completes asynchronously, so your wsClass
needs to tell the caller about completion after post is finished. A nice way to do this is to augment the sendData
method with a block of code supplied by the caller that should be run upon completion:
Change sendData:
to look like this:
// 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);
}];
}
The caller now 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 couple of notes about this: (1) I didn't add an error param to the block, you probably should. Check that and invoke the block with either nil and an error, or with the json output and error=nil. (2) Your code assumes that the json result parses as a dictionary. Make sure that's always true before you assume it in code. (3) Class names usually begin with caps.
Try this . 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"]);
}
}
You can use Semaphores for wiating till the block completes the execution and then return the value from 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;
}