Nice programing

sendAsynchronousRequest : queue : completionHandler를 사용하는 방법 :

nicepro 2020. 10. 20. 08:11
반응형

sendAsynchronousRequest : queue : completionHandler를 사용하는 방법 :


두 부분으로 된 질문

파트 1 : 데이터베이스에 대한 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);
    }
}

내가해야 할 일은 전화를 바꾸는 것 같아요

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

ASynchronous 버전

sendAsynchronousRequest:queue:completionHandler:

그러나 큐 또는 완료 핸들러에 무엇을 전달할지 잘 모르겠습니다. 모든 예제 / 솔루션은 대단히 감사하겠습니다.

2 부 : 멀티 태스킹에 대해 읽었으며 인터럽트가있는 경우 연결 요청이 완료되었는지 확인하여 지원하고 싶습니다. 나는이 예를 따르고있다

그것은 인터럽트가 발생하면 더 많은 시간을 얻는 방법에 대해 설명합니다. 나는 그것이 무엇을하는지 이해합니다. 그러나이 연결에 어떻게 적용하는지는 이해하지 못합니다. 적용 방법을 알아내는 데 도움이되는 예제 / 튜토리얼이 있다면 멋질 것입니다!


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의 이전 동작을 제공합니다. 그러나 파일에 쓰거나 압축을 풀 계획이라면 백그라운드 큐에서 완료 한 다음 UI 업데이트를 위해 비동기식을 메인 큐로 다시 보낼 수 있습니다.


나는 비슷한 문제에 대해 작업하고 있으며이 질문을 게시하고 여기에 명확한 답변을 얻었습니다 . 파트 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.

     [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

     }

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.

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:

 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 has been deprecated in Swift. Move to dataTaskWithRequest, luckily it is used pretty much the same way.

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

참고URL : https://stackoverflow.com/questions/9270447/how-to-use-sendasynchronousrequestqueuecompletionhandler

반응형