使用 NSURLSession 等待 HTTP 请求的响应 - Objective C
Wait response for HTTP request using NSURLSession - Objective C
现在我正在开发我的小 class,它有一个发送 POST 请求的方法。此方法用于 returning 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);
我的问题是我不想在回调块中执行代码,因为我需要等待响应才能 return 一个 ResponseModel 并且实现它的任何人都可以接收模型并制作其他的东西。
我一直在研究使用 NSURLConnection,因为它有一个执行同步请求的方法,但现在它已被弃用,所以我想知道:这是一种我可以使用代码中的内容等待响应的方法吗?
您可以使用 GCD 实现这样的同步请求:
swift代码
public static func requestSynchronousData(request: URLRequest) -> Data? {
var data: Data? = nil
let semaphore: DispatchSemaphore = DispatchSemaphore(value: 0)
let task = URLSession.shared.dataTask(with: request, completionHandler: {
taskData, _, error -> () in
data = taskData
if data == nil, let error = error {print(error)}
semaphore.signal()
})
task.resume()
_ = semaphore.wait(timeout: .distantFuture)
return data
}
Objective-C代码
+ (NSData *)requestSynchronousData:(NSURLRequest *)request {
__block NSData * data = nil;
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable taskData, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (error) {
NSLog(@"%@", error);
}
data = taskData;
dispatch_semaphore_signal(semaphore);
}];
[task resume];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
return data;
}
您可以使用dispatch_async来处理UI块内的交互
DummyModel * dummy = [[DummyModel alloc] init];
__block ResponseModel * result = [[ResponseModel alloc] init];
[HTTPRequest sendPOSTRequest1:dummy withResponse:^(ResponseModel *data) {
result = data;
dispatch_async(dispatch_get_main_queue(), ^{
// handle some ui interaction
});
NSLog(@"data %@",data);
}];
现在我正在开发我的小 class,它有一个发送 POST 请求的方法。此方法用于 returning 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);
我的问题是我不想在回调块中执行代码,因为我需要等待响应才能 return 一个 ResponseModel 并且实现它的任何人都可以接收模型并制作其他的东西。 我一直在研究使用 NSURLConnection,因为它有一个执行同步请求的方法,但现在它已被弃用,所以我想知道:这是一种我可以使用代码中的内容等待响应的方法吗?
您可以使用 GCD 实现这样的同步请求:
swift代码
public static func requestSynchronousData(request: URLRequest) -> Data? {
var data: Data? = nil
let semaphore: DispatchSemaphore = DispatchSemaphore(value: 0)
let task = URLSession.shared.dataTask(with: request, completionHandler: {
taskData, _, error -> () in
data = taskData
if data == nil, let error = error {print(error)}
semaphore.signal()
})
task.resume()
_ = semaphore.wait(timeout: .distantFuture)
return data
}
Objective-C代码
+ (NSData *)requestSynchronousData:(NSURLRequest *)request {
__block NSData * data = nil;
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable taskData, NSURLResponse * _Nullable response, NSError * _Nullable error) {
if (error) {
NSLog(@"%@", error);
}
data = taskData;
dispatch_semaphore_signal(semaphore);
}];
[task resume];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
return data;
}
您可以使用dispatch_async来处理UI块内的交互
DummyModel * dummy = [[DummyModel alloc] init];
__block ResponseModel * result = [[ResponseModel alloc] init];
[HTTPRequest sendPOSTRequest1:dummy withResponse:^(ResponseModel *data) {
result = data;
dispatch_async(dispatch_get_main_queue(), ^{
// handle some ui interaction
});
NSLog(@"data %@",data);
}];