如何通过NSURLConnection sendAsynchronousRequest取消异步调用?

时间:2011-11-09 22:55:25

标签: iphone objective-c ios ios5 nsurlconnection

我有一个Web服务调用实时对用户输入执行一些验证。我想在验证上使用[NSURLConnection sendAsynchronousRequest](在iOS 5中引入),但如果用户同时更改输入字段内容,则取消它。取消当前请求的最佳方法是什么?

2 个答案:

答案 0 :(得分:19)

似乎没有一种好方法可以做到这一点。解决方案似乎是在您需要取消请求的情况下不使用新的[NSURLConnection sendAsynchronousRequest]

答案 1 :(得分:3)

我设法通过将sendAsynchronousRequest方法放在单独的DownloadWrapper类中来实现此目的,如下所示:

//
//  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变量(在接口声明中)并实现处理响应或缺少响应的协议方法之外,我还会执行以下操作:

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

然后,我只需执行以下操作即可取消&#39;视图即将消失时的连接:

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

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

就这么简单。这有望模仿记录的cancel方法,该方法声明它执行以下操作:

  

调用此方法后,接收方的代理将不再   接收此NSURLConnection的任何消息。

我担心这种(有点天真)的方法意味着数据包仍然会响应我们的网址请求 - 只是我们不再“聆听”#作为代表。但后来我才意识到,一旦URL请求被发送出来,就没有办法阻止回复给我们 - 我们只能忽略它(如果不是在这个级别,那么仍然处于较低级别)网络层次结构)。如果我错了,请纠正我。

无论哪种方式,希望这有帮助。