it-swarm.com.ru

как использовать sendAsynchronousRequest: queue: завершениеHandler:

Вопрос из двух частей

Часть первая: Я пытаюсь создать асинхронный запрос к моей базе данных. В настоящее время я делаю это синхронно, однако я хочу изучить оба пути, чтобы лучше понять, что происходит.

В настоящее время я настроил свой синхронный вызов, как это.

- (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:

однако я не уверен, что передать в очередь или завершение Хендлер ... Любые примеры/решения будет принята с благодарностью.

Часть вторая: Я читал о многозадачности и хотел бы поддержать ее, убедившись, что мои запросы на подключение выполнены, если есть прерывание. Я следил за этим пример

В нем объясняется, как выиграть больше времени, если происходит прерывание, я понимаю, что он делает .. но не как применить его к этому соединению? если у вас есть примеры/учебники, которые помогут мне понять, как их применять, это было бы здорово!

74
C.Johns

Часть 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];
}];
114
mbh

Вот образец:

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

     }];
38
Flea

Для параметра очереди, попробуйте это волшебство:

[NSOperationQueue mainQueue]

Это прекрасно работает, если вы обновляете пользовательский интерфейс по завершении запроса, так как основная очередь является основным потоком. По сути, это дает вам предыдущее поведение NSURLConnection. Однако, если вы планируете записывать в файл или распаковывать, вы можете выполнить его в фоновой очереди и затем отправить асинхронную обратно в основную очередь для обновлений пользовательского интерфейса.

26
malhal

Я работал над аналогичной проблемой, я опубликовал этот вопрос и получил четкий ответ здесь , я надеюсь, что это поможет с частью 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

     }
9
Recycled Steel

Поскольку sendAsynchronousRequest:urlRequest queue:queue completionHandler: устарел в iOS 9, он предлагает использовать вместо него NSURLSession'S -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];
4
AechoLiu

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()
}
2
Bhavesh Patel