【发布时间】:2020-02-10 01:40:37
【问题描述】:
现在我正在开发一个小类,它有一个发送 POST 请求的方法。该方法旨在返回一个 ResponseModel(基本上有两个 ivars:代码、消息),该模型将从响应映射。
我正在使用dataTaskWithRequest:urlRequest completionHandler: 方法。像这样:
+ (void)sendPOSTRequest1:(id)data withResponse:(void (^) (ResponseModel * data) )taskResponse {
NSError *error = nil;
NSMutableURLRequest * urlRequest = [self getRequestObject];
[urlRequest setHTTPMethod:@"POST"];
NSData * requestData = [self encodeAndEncrypt:data];
[urlRequest setHTTPBody:requestData];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session
dataTaskWithRequest:urlRequest
completionHandler:
^(NSData *data, NSURLResponse *response, NSError *error) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
ResponseModel * responseModel = [NSKeyedUnarchiver
unarchivedObjectOfClass:[ResponseModel class]
fromData:data
error:&error];
taskResponse(responseModel);
}];
[dataTask resume];
}
并以这种方式调用该方法:
DummyModel * dummy = [[DummyModel alloc] init];
__block ResponseModel * result = [[ResponseModel alloc] init];
[HTTPRequest sendPOSTRequest1:dummy withResponse:^(ResponseModel *data) {
result = data;
NSLog(@"data %@",data);
}];
// It`s not sure that the asyncronous request has already finished by this point
NSLog(@"POST result : %@",result);
我的问题是我不想在回调块中执行代码,因为我需要等待响应才能返回一个 ResponseModel 并且执行此操作的任何人都可以接收该模型并制作其他东西。 我一直在研究使用 NSURLConnection 因为它有一个执行同步请求的方法,但现在它已被弃用,所以我想知道:这是一种我可以使用代码中的内容等待响应的方法吗?
【问题讨论】:
-
不,你总是不想等待。无论谁调用您的
sendPOSTRequest方法,都应该采用与此处完全相同的异步模式(例如完成块等)。我知道,如果你把它做成一个只返回值的同步方法,感觉会很明智和容易,但它几乎总是与应该做的完全相反。而且,正如您所指出的,您也不想使用已弃用的NSURLConnection。新 API 不提供同步方法是有原因的,因此请采用异步模式。 -
嗨,@Rob,谢谢你的回答。那么,既然您提到要附加到这个 Asynchornous 模式,是否仍然可以处理块内的一些 UI 交互(当方法被调用时)以便向用户检索信息?
-
是的,您可以在传递给
sendPOSTRequest的完成处理程序块中执行此操作。唯一的技巧是您只想将该块调度 ivar 和 UI 更新回主队列,例如dispatch_async(dispatch_get_main_queue(), ^{ ... });
标签: ios objective-c cocoa-touch request