Objective-C GET请求 - 如何不冻结UI,等待响应?

时间:2014-11-27 19:13:04

标签: ios objective-c cocoa-touch

我正在使用以下代码发出简单的GET请求:

NSString *urlStr = [@"http://192.168.1.107/Server.Mobile/test.ashx?rp="
                          stringByAppendingString:[rpText 
                               stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlStr]                                                          
                                     cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData
                                     timeoutInterval:100];

[request setHTTPMethod: @"GET"];

NSError *requestError;
NSURLResponse *urlResponse = nil;
NSData *response1 = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:&requestError];
NSString *txt = [[NSString alloc] initWithData:response1 encoding:NSUTF8StringEncoding];

但是,在执行时,我试图显示UIAlertView,然后在请求完成时将其解除。

我知道如何显示/隐藏提醒,但我无法将其与请求同步。该请求冻结了UI,因此在完成后,AlertView会立即显示并隐藏:

alert = [[UIAlertView alloc] initWithTitle:@"Please, wait..." message:nil delegate:self cancelButtonTitle:nil otherButtonTitles:nil, nil];
[alert show];

// ... Perform get request...

[alert dismissWithClickedButtonIndex:0 animated:YES];

另一方面,如果我将请求分配给异步操作,例如dispatch_async,我就无法调用解雇。它只是没有关闭AlertView

alert = [[UIAlertView alloc] initWithTitle:@"Please, wait..." message:nil delegate:self cancelButtonTitle:nil otherButtonTitles:nil, nil];
[alert show];

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    // ... Perform get request...

    [alert dismissWithClickedButtonIndex:0 animated:YES];
});

如何显示警报,执行等待响应的请求,然后关闭警报?

我是iOS开发的新手......

4 个答案:

答案 0 :(得分:1)

NSURLConnection可能以异步方式运行。使用NSURLConnection初始化程序创建initWithRequest:delegate:,将自己作为委托。请求完成后,您将收到connectionDidFinishLoading:回调,您可以从中回复更新用户界面。

或者更好的是,使用新的NSURLSession API来实现同样的目标。

答案 1 :(得分:1)

进行异步网络呼叫。使用现有代码的最简单方法是sendAsynchronousRequest:queue:completionHandler:

NSString *urlStr = [@"http://192.168.1.107/Server.Mobile/test.ashx?rp="
                          stringByAppendingString:[rpText 
                               stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];

alert = [[UIAlertView alloc] initWithTitle:@"Please, wait..." message:nil delegate:self cancelButtonTitle:nil otherButtonTitles:nil, nil];
[alert show];

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlStr]                                                          
                                     cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData
                                     timeoutInterval:100];

[request setHTTPMethod: @"GET"];

NSError *requestError;
NSURLResponse *urlResponse = nil;


(^handler)(NSURLResponse *response, NSData *data, NSError *error);

handler = ^(NSURLResponse *response, NSData *data, NSError *error){
    if(error == nil){
        [alert dismissWithClickedButtonIndex:0 animated:YES];

    } else {
        // handle error
    }
};

[NSURLConnection sendAsynchronousRequest:request
                                   queue:[NSOperationQueue mainQueue]
                       completionHandler:handler];

答案 2 :(得分:0)

在我看来,这不是最好的方法。但是这段代码解决了你的问题:

     alert = [[UIAlertView alloc] initWithTitle:@"Please, wait..." message:nil delegate:self cancelButtonTitle:nil otherButtonTitles:nil, nil];
[alert show];

dispatch_async(dispatch_queue_create("makeRequest", nil), ^{

    NSString *urlStr = [@"http://192.168.1.107/Server.Mobile/test.ashx?rp="
                        stringByAppendingString:[rpText
                                                 stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlStr]
                                                           cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData
                                                       timeoutInterval:100];

    [request setHTTPMethod: @"GET"];

    NSError *requestError;
    NSURLResponse *urlResponse = nil;
    NSData *response1 = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:&requestError];
    NSString *txt = [[NSString alloc] initWithData:response1 encoding:NSUTF8StringEncoding];

    dispatch_async(dispatch_get_main_queue(), ^{

        [alert dismissWithClickedButtonIndex:0 animated:YES];

    });



});

答案 3 :(得分:0)

您可以使用AFNetworking这是一个简化异步请求的库。您可以使用此代码

AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:@"http://example.com/resources.json" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSLog(@"JSON: %@", responseObject);
    // UPDATE YOUR UI HERE
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"Error: %@", error);
}];