我的目标场景: 尝试向我的应用程序服务器发送一个简单的HTTP请求,并获得一个json响应。基于json响应,我需要执行segue操作。
我当前的情景: 这发生在我的系统中。经过太多延迟后,我得到了我的HTTP请求的json响应,因为我的响应是在延迟之后,执行segue甚至没有检查响应中的数据。
我的要求 如何让我的segue等到我收到HTTP请求的响应?
[application getjsonResponse];
if([[defaults stringForKey:@"status"] isEqual:@"success"])
{
return YES;
}
这些是我使用的代码行。我不希望我的线程在条件执行时执行此操作,除非我得到HTTP请求的响应。
到目前为止我尝试了:
好奇的问题
当我从桌面浏览器(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];
}
答案 0 :(得分:1)
确定。你的问题有很多不一致之处。例如,您谈到执行segue但您的代码不包含任何操作。
无论如何,首先我会说停止/暂停你的应用程序的主线程是一个坏主意。期。当你做这样的事情,或以任何方式在主线程上运行需要花费大量时间执行的代码时,你有效地使应用程序无响应,并且用户将无响应的应用程序视为质量差,因此不是值得使用。
以下是我将如何重写您的代码以执行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];
```
答案 1 :(得分:0)
NSURLSessionDataTask已由系统异步执行。
因此,如果您想在从请求中接收数据后执行segue,只需将您的segue代码放在完成块中。
在您的情况下,在处理响应数据之后,例如在行:
之后[defaults synchronize];
请注意,在再次对主线程进行操作之前,应首先调度到主线程。
dispatch_async(dispatch_get_main_queue(), ^{
// YOUR SEGUE HERE
});