如何获取数据从NSURLSessionDataTask返回

我有一个注册视图控制器处理所有的用户input,并调用另一个类(wsClass)传递给它的函数,该数据作为NSDictionary。

wsClass中的函数被调用并build立连接,数据从服务器返回并在会话中可用。

我的问题是,如何返回数据到注册视图控制器,最初调用函数,它总是空的。

这是在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]; 

这是在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; 

}

这个post是asynchronous完成的,所以你的wsClass需要在完成后告诉调用者完成。 一个很好的方法是使用由调用者提供的代码块来增加sendData方法,该代码块应该在完成时运行:

改变sendData:看起来像这样:

 // 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); }]; } 

调用者现在看起来像这样:

 // 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" }]; 

关于这一点只是一些笔记:(1)我没有添加一个错误参数的块,你可能应该。 检查并调用块的nil和一个错误,或与json输出和error = nil。 (2)你的代码假定json结果parsing为字典。 确保在代码假设之前总是如此。 (3)class级名称通常以大写字母开头。

这可能工作。

  1. 为NSDict添加一个接口variablesnsDictVariable,或者在类中检索的任何东西
  2. 在SendData中分配它:self.nsDictVariable = ….

尝试这个 。 这将工作得很好。

 -(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"]); } } 

您可以使用Semaphores进行wading,直到块完成执行,然后从函数返回值

 - (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; 

}