我的目标场景: 尝试向我的应用程序服务器发送一个简单的 HTTP 请求并获得一个 json 响应作为返回。根据 json 响应,我需要执行一个 segue 操作。
我当前的场景: 这发生在我的系统中。延迟太多后,我的 HTTP 请求得到了 json 响应,因为我的响应是在延迟之后,所以执行 segue 时甚至没有检查响应中的数据。
我的要求 如何让我的 segue 等到我收到 HTTP 请求的响应?
[application getjsonResponse];
if([[defaults stringForKey:@"status"] isEqual:@"success"])
{
return YES;
}
这些是我使用的代码行。除非我的 HTTP 请求得到响应,否则我不希望我的线程执行此 if 条件。
到目前为止我尝试过的:
- 我试过线程休眠方法,它有时有效,有时无效。
- 在收到回复之前,我一直重复 while 循环。
好奇的问题
当我从桌面浏览器 (Chrome) 或移动浏览器向我的应用程序发出相同的请求时,我会立即得到响应,但是当我使用代码时,我似乎在延迟 10 秒或更长时间后才得到结果。这是为什么?
这是我用来向我的应用程序服务器发送 http 请求的一段代码。
-(void)getjsonResponse
{
NSURL *url=[NSURL URLWithString: URLForApplication];
NSURLRequest *req=[NSURLRequest requestWithURL:url];
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask connection=[session dataTaskWithRequest:req completionHandler:^(NSData data, NSURLResponse response, NSError error)
{
if (!error){
// Success
if ([response isKindOfClass:[NSHTTPURLResponse class]])
{
NSError *jsonError;
NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonError];
if (jsonError)
{ // Error Parsing JSON
}
else
{ // Success Parsing JSON
// Log NSDictionary response:
NSLog(@"%@",jsonResponse);
{
NSString * statusCode=[[NSString alloc]init];
statusCode=jsonResponse[@"statusCode"];
_statusOtpResponse=jsonResponse[@"status"];
NSLog(@"status value: %@",_statusOtpResponse);
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:_statusOtpResponse forKey:@"status"];
[defaults setObject:statusCode forKey:@"statuscodeOtp"];
[defaults synchronize];
}
}
}
else
{
//Web server is returning an error
}
}
else
{
// Fail
NSLog(@"error : %@", error.description);
}
}];
if(connection){
[connection resume];
}
最佳答案
好的。你的问题有很多不一致之处。例如,您谈论执行 segue,但您的代码不包含执行此操作的任何内容。
无论如何,首先我要说停止/暂停应用的主线程是个坏主意。时期。一旦你做了类似的事情,或者以任何方式在主线程上运行需要大量时间执行的代码,你实际上会使你的应用程序无响应,而无响应的应用程序被用户视为质量差,因此不会值得使用。
以下是我将如何重写您的代码以执行转场。注意主线程上的回调。
NSURL *url = [NSURL URLWithString: URLForApplication];
NSURLRequest *req = [NSURLRequest requestWithURL:url];
NSURLSession *session = [NSURLSession sharedSession];
// Do something here to indicate a server query is executing.
// For example, displaying a UIActivityIndicatorView
// Note: you had a missing '*' on this line
NSURLSessionDataTask *connection = [session dataTaskWithRequest:req completionHandler:^(NSData data, NSURLResponse response, NSError error) {
// First error check.
if (error) {
// Log and/or display alert with error message and finish.
// Reset display to non busy mode on main thread.
NSLog(@"error : %@", error.description);
return;
}
// We're here, so request was a success
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
NSError *jsonError;
NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonError];
if (jsonError) {
// Log and/or display alert with error message and finish.
// Reset display to non busy mode on main thread.
NSLog(@"error : %@", error.description);
return;
}
// We're here, so JSON parse was a success
NSLog(@"%@", jsonResponse);
NSString *statusCode = jsonResponse[@"statusCode"];
NSString *statusOtpResponse = jsonResponse[@"status"];
if (/* test variables to decide if to execute the segue */) {
// Now we know we want to execute the segue.
dispatch_async(dispatch_get_main_queue(), ^{
[self performSegueWithIdentifier:@"segue-id" sender:self];
});
}
// Removed your code for storing response codes in user defaults because I simply could not see why you would do that.
}];
// Execute
[connection resume];
```
关于ios - 如何停止主 ui 线程,直到我收到来自 http 请求的响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43517234/