如何使用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部分有所帮助。
对于第1部分,这里提到的其他人很好,但是你需要添加另一个检查(我已经修改了下面的答案)。 有可能你的请求会返回一个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() }