如何使用sendAsynchronousRequest:queue:completionHandler:

C.J*_*hns 74 iphone nsurlconnection ios

两部分问题

第一部分: 我正在尝试为我的数据库创建一个ASynchronous请求.我目前正在同步这样做,但我想学习两种方法来更好地理解最新情况.

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

- (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);
    }
}
Run Code Online (Sandbox Code Playgroud)

我想我需要做的就是更换电话

NSData *result = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
Run Code Online (Sandbox Code Playgroud)

与ASynchronous版本

sendAsynchronousRequest:queue:completionHandler:
Run Code Online (Sandbox Code Playgroud)

但是我不确定要传递给队列或者完成任务的内容......任何示例/解决方案都将非常感激.

第二部分: 我一直在阅读有关多任务的内容,我想通过确保在有中断的情况下完成连接请求来支持它.我一直在关注这个例子

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

mbh*_*mbh 114

第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];
}];
Run Code Online (Sandbox Code Playgroud)

  • 我相信`NSURLErrorTimedOut`是'ERROR_CODE_TIMEOUT`的可接受值. (12认同)
  • 这些方法都在你的课堂上.您可以根据需要重命名这些方法.或者没有它们.但把代码放在if then else本身.或者你可以像这样打电话[self receivedData:data]; (2认同)
  • 注意:`sendAsynchronousRequest:urlRequest queue:queue completionHandler:`已在iOS 9中弃用 (2认同)

Fle*_*lea 38

这是一个示例:

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

     }];
Run Code Online (Sandbox Code Playgroud)

  • 我正在使用ARC,只是没有提到它.谢谢你的提问! (3认同)

mal*_*hal 26

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

[NSOperationQueue mainQueue]
Run Code Online (Sandbox Code Playgroud)

如果您在请求完成时更新UI,那么这很有用,因为主队列是主线程.它基本上为您提供NSURLConnection的先前行为.但是,如果您计划写入文件或解压缩,则可以在后台队列上完成,然后将异步调度回主队列以进行UI更新.


Rec*_*eel 9

我一直在研究类似的问题,我发布了这个问题并在这里得到了明确的答案,我希望这有助于第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

     }
Run Code Online (Sandbox Code Playgroud)