如何使用 sendAsynousRequest: queue: CompletionHandler:

两个问题

第一部分: 我试图创建一个异步请求到我的数据库。我目前正在做它同步然而,我想学习两种方式,以更好地理解正在发生的事情。

目前我已经像这样设置了我的同步调用。

- (IBAction)setRequestString:(NSString *)string
{
//Set database address
NSMutableString *databaseURL = [[NSMutableString alloc] initWithString:@"http://127.0.0.1:8778/instacodeData/"]; // imac development


//PHP file name is being set from the parent view
[databaseURL appendString:string];


//call ASIHTTP delegates (Used to connect to database)
NSURL *url = [NSURL URLWithString:databaseURL];


//SynchronousRequest to grab the data
NSURLRequest *request = [NSURLRequest requestWithURL:url];
NSError *error;
NSURLResponse *response;


NSData *result = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
if (!result) {
//Display error message here
NSLog(@"Error");
} else {


//TODO: set up stuff that needs to work on the data here.
NSString* newStr = [[NSString alloc] initWithData:result encoding:NSUTF8StringEncoding];
NSLog(@"%@", newStr);
}
}

我觉得我应该换掉那个电话

NSData *result = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

使用异步版本

sendAsynchronousRequest:queue:completionHandler:

然而,我不确定该将什么传递给 queue 或 CompletionHandler... 任何示例/解决方案都将非常感谢。

第二部分: 我一直在阅读有关多任务,我想支持它,以确保我的连接请求完成,如果有一个中断。我一直在跟踪这个 例子

它解释了如何获得更多的时间,如果一个中断发生,我明白它在做什么。.但不知道如何将其应用于这种连接?如果你有任何例子/教程来帮助我弄清楚如何应用它,那将是非常棒的!

85382 次浏览

第一部分:

NSURL *url = [NSURL URLWithString:urlString];


NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];


[NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
if ([data length] > 0 && error == nil)
[delegate receivedData:data];
else if ([data length] == 0 && error == nil)
[delegate emptyReply];
else if (error != nil && error.code == ERROR_CODE_TIMEOUT)
[delegate timedOut];
else if (error != nil)
[delegate downloadError:error];
}];

下面是一个例子:

NSString *urlAsString = @"http://www.cnn.com";
NSURL *url = [NSURL URLWithString:urlAsString];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];




[NSURLConnection
sendAsynchronousRequest:urlRequest
queue:[[NSOperationQueue alloc] init]
completionHandler:^(NSURLResponse *response,
NSData *data,
NSError *error)
{


if ([data length] >0 && error == nil)
{


// DO YOUR WORK HERE


}
else if ([data length] == 0 && error == nil)
{
NSLog(@"Nothing was downloaded.");
}
else if (error != nil){
NSLog(@"Error = %@", error);
}


}];

我一直在研究一个类似的问题,我发布了这个问题,并得到了一个明确的答案 给你,我希望这有助于第2部分。

对于第1部分,这里提到的其他部分都很好,但是您需要添加另一个检查(我已经修改了下面的答案)。您的请求可能会返回一个404错误(页面未找到) ,在这种情况下,您不会得到错误和数据将 > 0。200是一个很好的响应,您也可以检查 StatusCode 中的404或其他内容。

     [NSURLConnection
sendAsynchronousRequest:urlRequest
queue:[[NSOperationQueue alloc] init]
completionHandler:^(NSURLResponse *response,
NSData *data,
NSError *error)
{
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
if ([data length] >0 && error == nil && [httpResponse statusCode] == 200)
{


// DO YOUR WORK HERE


}

对于队列参数,请尝试以下魔法:

[NSOperationQueue mainQueue]

因为主队列是主线程,所以如果您在请求完成时更新 UI,那么这样做非常有效。它基本上给出了 NSULConnection 之前的行为。然而,如果您计划写入文件或解压缩,那么您可以在后台队列上完成,然后将异步分派回主队列以进行 UI 更新。

由于 sendAsynchronousRequest:urlRequest queue:queue completionHandler:在 iOS9中已经被弃用,因此它将建议改用 ABC1是 -dataTaskWithRequest:completionHandler:。从 IOS7及更高版本开始就有了。

原文:

 NSURL *URL = [NSURL URLWithString:@"http://example.com"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];


[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
// ...
}];

译者:

 NSURL *URL = [NSURL URLWithString:@"http://example.com"];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];


NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request
completionHandler:
^(NSData *data, NSURLResponse *response, NSError *error) {
// ...
}];


[task resume];

在 Swift 中,sendAsynchronousRequest已被弃用。请转到 dataTaskWithRequest,幸运的是,它的使用方法大致相同。

if let url = NSURL(string:"http://your_url") {


let request:NSURLRequest = NSURLRequest(URL: url)
let config = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: config)


let task = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in


});


task.resume()
}