![](/img/trans.png)
[英]How to get return value from NSURLSessionDataTask and call block?
[英]How to get data to return from NSURLSessionDataTask
我有一个注册视图控制器,它处理所有用户输入并调用传递给它的另一个类(wsClass)中的函数,该数据作为NSDictionary。
调用wsClass中的函数并建立连接,并从服务器返回数据并在会话中使用。
我的问题是如何将该数据返回到最初调用该函数的注册视图控制器,它始终是空的。
这是在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;
}
帖子以异步方式完成,因此你的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结果作为字典解析。 在代码中假设它之前,请确保始终为true。 (3)班级名称通常以大写字母开头。
您可以使用信号量进行转换,直到块完成执行,然后从函数返回值
- (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;
}
这可能会奏效。
试试这个 。 这将很好。
-(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"]);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.