如何使用sendAsynchronousRequest:queue:completionHandler:

两部分问题

第一部分:我试图创build一个ASSQL请求到我的数据库。 我目前正在做同步,但是我想学习两种方法,以更好地理解发生了什么事情。

目前我已经build立了像这样的同步呼叫。

- (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]; 

与asynchronous版本

 sendAsynchronousRequest:queue:completionHandler: 

但是我不知道要传递给队列或者completionHandler …任何示例/解决scheme将不胜感激。

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

在这里它解释了如何获得更多的时间,如果中断发生,我明白它在做什么,但不是如何将其应用于此连接? 如果你有任何的例子/教程,以帮助我弄清楚如何应用它,这将是太棒了!

第1部分:

 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); } }]; 

对于队列参数,试试这个魔法:

 [NSOperationQueue mainQueue] 

如果由于主队列是主线程而在请求完成时更新UI,这将非常有效。 它基本上给你NSURLConnection以前的行为。 但是,如果您计划写入文件或解压缩,则可以在后台队列上完成,然后将asynchronous发送回主更新的主队列。

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

对于第一部分,这里提到的其他人都很好,但是您需要添加另一个支票(我在下面修改了一个答案)。 有可能你的请求会返回一个404错误(页面未find),在这种情况下,你将不会得到错误和数据将大于0. 200是一个很好的回应,你也可以检查状态码为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 } 

由于在iOS 9中已经弃用了sendAsynchronousRequest:urlRequest queue:queue completionHandler:并且会build议使用NSURLSession-dataTaskWithRequest:completionHandler:来代替。 它从iOS 7及更高版本开始可用。

原版的:

  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) { // ... }]; 

通过NSURLSession:

  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]; 

sendAsynchronousRequest在Swift中已被弃用。 移动到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() }