ios - 如何停止主 ui 线程,直到我收到来自 http 请求的响应

标签 ios objective-c

我的目标场景: 尝试向我的应用程序服务器发送一个简单的 HTTP 请求并获得一个 json 响应作为返回。根据 json 响应,我需要执行一个 segue 操作。

我当前的场景: 这发生在我的系统中。延迟太多后,我的 HTTP 请求得到了 json 响应,因为我的响应是在延迟之后,所以执行 segue 时甚至没有检查响应中的数据。

我的要求 如何让我的 segue 等到我收到 HTTP 请求的响应?

[application getjsonResponse];
     if([[defaults stringForKey:@"status"] isEqual:@"success"])
        {

            return YES;

        }

这些是我使用的代码行。除非我的 HTTP 请求得到响应,否则我不希望我的线程执行此 if 条件。

到目前为止我尝试过的:

  1. 我试过线程休眠方法,它有时有效,有时无效。
  2. 在收到回复之前,我一直重复 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/

相关文章:

ios - 为 iphone se 创建自动布局?

ios - 通用类型

ios - 如何从 Firebase 检索数据?

ios - 在 iOS 中显示自定义 VoIP 应用程序的通话状态栏(双高)

ios - 从 NSTimer 回到主线程

ios - 如何有条件地为导航 Controller 设置 Root View Controller

ios - UIViewController<UISplitViewControllerDelegate> 与 UISplitViewController

ios - 有没有办法在 SwiftUI 中隐藏搜索栏

jquery - 手动触发专注于输入 Iphone 问题

objective-c - 创建的嵌入式 NSButton 显示不正确