ios 如何使用 sendAsynchronousRequest:queue:completionHandler:

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9270447/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 16:50:11  来源:igfitidea点击:

how to use sendAsynchronousRequest:queue:completionHandler:

iphoneiosnsurlconnection

提问by C.Johns

Two part question

两部分问题

Part one:I am trying to create an ASynchronous request to my database. I am currently doing it Synchronously however I want to learn both ways to better my understanding of whats going on.

第一部分:我正在尝试为我的数据库创建一个 ASynchronous 请求。我目前正在同步进行,但是我想同时学习这两种方法来更好地理解正在发生的事情。

Currently I have set up my Synchronous call like this.

目前我已经像这样设置了我的同步呼叫。

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

I think what I need to do is replace the call

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

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

with the ASynchronous version

与 ASynchronous 版本

sendAsynchronousRequest:queue:completionHandler:

however I'm not sure what to pass to queue or completionHandler... Any examples/solutions would be greatly appreciated.

但是我不确定要传递给队列或完成处理程序的内容......任何示例/解决方案将不胜感激。

Part two:I have been reading about multi tasking and I would like to support it by making sure my connection requests complete if there is an interrupt. I have been following this example

第二部分:我一直在阅读有关多任务处理的文章,我想通过确保在出现中断时完成连接请求来支持它。我一直在关注这个例子

In it it explains how to gain more time if an interrupt occurs, I understand what its doing.. but not how to apply it to this connection? if you have any examples/tutorials to help me figure out how to apply it that would be awesome!

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

回答by mbh

PArt 1:

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

回答by Flea

Here is a sample:

这是一个示例:

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

     }];

回答by malhal

For the queue param, try this magic:

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

[NSOperationQueue mainQueue]

This works great if you are updating the UI on completion of the request since main queue is the main thread. It essentially gives you the previous behavior of NSURLConnection. If however you plan on writing to file or decompressing then you can complete on a background queue and then dispatch async back to the main queue for the UI updates.

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

回答by Recycled Steel

I have been working on a similar problem, I posted this question and got a clear answer here, I hope that helps with Part 2.

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

For part 1 what the others mentioned here are good but you need to add another check (I have modified an answer below). It is possible that your request will return say a 404 Error (page not found) in which case you will not get and error and data will be > 0. The 200 is a good response, you could also check the StatusCode for 404 or whatever.

对于第 1 部分,这里提到的其他人很好,但您需要添加另一张支票(我修改了下面的答案)。您的请求可能会返回 404 错误(找不到页面),在这种情况下您将不会收到错误并且数据将 > 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

     }

回答by AechoLiu

Since sendAsynchronousRequest:urlRequest queue:queue completionHandler:has been deprecated in iOS 9, and it will suggest to use NSURLSession's -dataTaskWithRequest:completionHandler:instead. It is available since iOS 7 and later.

由于sendAsynchronousRequest:urlRequest queue:queue completionHandler:已在 iOS 9 中弃用,因此建议使用NSURLSession's-dataTaskWithRequest:completionHandler:代替。它从iOS 7 及更高版本开始可用。

Original:

原来的:

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

By NSURLSession:

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

回答by Bhavesh Patel

sendAsynchronousRequesthas been deprecated in Swift. Move to dataTaskWithRequest, luckily it is used pretty much the same way.

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