web-dev-qa-db-ja.com

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:

ただし、キューまたはcompletionHandlerに何を渡すかわからない...どんな例/解決策も大歓迎です。

パート2:私はマルチタスクについて読んでおり、割り込みがある場合に接続要求が完了することを確認することでそれをサポートしたいと思います。私はこれに従いました

その中で、割り込みが発生した場合により多くの時間を獲得する方法を説明し、その動作を理解しています。あなたが私がそれを適用する方法を見つけ出すのに役立つ例/チュートリアルがあれば、それは素晴らしいでしょう!

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]

メインキューはメインスレッドであるため、リクエストの完了時にUIを更新する場合、これは非常に効果的です。基本的に、NSURLConnectionの以前の動作を提供します。ただし、ファイルへの書き込みまたは圧縮解除を予定している場合は、バックグラウンドキューで完了し、UI更新のために非同期をメインキューにディスパッチできます。

26
malhal

私は同様の問題に取り組んできました。この質問を投稿し、明確な答えを得ました here 、パート2に役立つことを願っています。

パート1では、他の人がここで言及したことは良いことですが、別のチェックを追加する必要があります(以下の回答を修正しました)。リクエストが404エラー(ページが見つかりません)を返す可能性があります。この場合、エラーは取得されず、データは0を超えます。200は適切な応答です。 。

     [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-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