2011-11-09 1 views
6

私はリアルタイムでユーザー入力に関する検証を実行するWebサービスコールを持っています。 (iOS 5で導入された)検証に[NSURLConnection sendAsynchronousRequest]を使用したいが、ユーザが入力フィールドの内容をその間に変更した場合はキャンセルする。現在のリクエストをキャンセルする最良の方法は何ですか?NSURLConnection sendAsynchronousRequestを使用して非同期呼び出しをキャンセルするにはどうすればよいですか?

答えて

19

これを行う良い方法はないようです。要求をキャンセルする必要がある状況では、解決策は新しい[NSURLConnection sendAsynchronousRequest]を使用しないように思われます。私は次のように、別々のDownloadWrapperクラスでsendAsynchronousRequestメソッドを置くことによって、これを行うことができた

+0

これは正しくありません。 [私のポストは、以下を参照してください(http://stackoverflow.com/a/25784367/1255674)。 – Robert

3

// 
// DownloadWrapper.h 
// 
// Created by Ahmed Khalaf on 16/12/11. 
// Copyright (c) 2011 arkuana. All rights reserved. 
// 

#import <Foundation/Foundation.h> 

@protocol DownloadWrapperDelegate 
- (void)receivedData:(NSData *)data; 
- (void)emptyReply; 
- (void)timedOut; 
- (void)downloadError:(NSError *)error; 
@end 

@interface DownloadWrapper : NSObject { 
    id<DownloadWrapperDelegate> delegate; 
} 
@property(nonatomic, retain) id<DownloadWrapperDelegate> delegate; 
- (void)downloadContentsOfURL:(NSString *)urlString; 
@end 

@implementation DownloadWrapper 
@synthesize delegate; 

- (void)downloadContentsOfURL:(NSString *)urlString 
{ 
    NSURL *url = [NSURL URLWithString:urlString]; 

    NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:TIMEOUT_INTERVAL]; 
    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]; 
    }]; 
} 
@end 

このクラスを利用するためには、私は(DownloadWrapper *downloadWrapper変数を宣言することに加えて、次の操作を行いインタフェース宣言内)および応答、または1つの欠如処理プロトコル実装方法:次に

NSString *urlString = @"http://yoursite.com/page/to/download.html"; 
downloadWrapper = [DownloadWrapper alloc]; 
downloadWrapper.delegate = self; 
[downloadWrapper downloadContentsOfURL:urlString]; 

をI単にビュージしようとするとき、接続を「キャンセル」に次の手順を実行しサッピア:

- (void)viewDidUnload 
{ 
    [super viewDidUnload]; 
    downloadWrapper = nil; 
} 

- (void)viewWillDisappear:(BOOL)animated 
{ 
    [super viewWillDisappear:animated]; 
    [downloadWrapper setDelegate:nil]; 
} 

これは簡単です。これがうまくいけば、それは次のことを行いと述べている文書cancel方法、模倣する:このメソッドが呼び出されると

を、受信機のデリゲートは、もはや このNSURLConnectionのために任意のメッセージを受信しません。

私はこの(やや素朴な)方法は、URLリクエストに応じてデータパケットが引き続き送信されることを意味していました。私たちはもはやデリゲートとしてリッスンしません。しかし、URLリクエストが送信されると、応答が私たちに返って来るのを止める方法がないことに気付きました。私たちはそれを無視することができます(このレベルではない場合でも、ネットワーク階層の下位レベルであっても) 。私が間違っているなら、私を修正してください。

いずれにしても、これが役立ちます。

+0

このソリューションで私が持っている1つの問題は、一度に1つの代理人しか持つことができないということです。 sendAsynchronousRequest:queue:completionHandler:のメリットの1つは、さまざまなオブジェクトからの多数の要求でそれを砲撃することができることです。ラッパーデリゲートが生きているが、元のリクエストオブジェクトがクラッシュしていない場合。これは私がグローバルAPIClientでこのメソッドを使用しようとしたときの問題でした。 私はMicahに同意しますが、これは簡単な実装のための実行可能な解決策になります。 – GnarlyDog

+2

あなたはそうです、それは私が必要としていたものであっても、あまりにも単純すぎました。私はその後、私のアプローチを変更し、代わりにNick Lockwoodの[RequestQueue](https://github.com/nicklockwood/RequestQueue)クラスを利用しました。すべての(並行して)要求を取り消すか、必要に応じて特定の要求を取り消す方法があります。 – pxlshpr

関連する問題