【发布时间】:2011-12-25 18:02:42
【问题描述】:
我有一个 Web 服务调用实时对用户输入执行一些验证。我想在验证中使用[NSURLConnection sendAsynchronousRequest](在 iOS 5 中引入),但如果用户同时更改输入字段内容,请取消它。取消当前请求的最佳方法是什么?
【问题讨论】:
标签: iphone objective-c ios ios5 nsurlconnection
我有一个 Web 服务调用实时对用户输入执行一些验证。我想在验证中使用[NSURLConnection sendAsynchronousRequest](在 iOS 5 中引入),但如果用户同时更改输入字段内容,请取消它。取消当前请求的最佳方法是什么?
【问题讨论】:
标签: iphone objective-c ios ios5 nsurlconnection
我已经设法通过将 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];
然后,当视图即将消失时,我只需执行以下操作即可“取消”连接:
- (void)viewDidUnload
{
[super viewDidUnload];
downloadWrapper = nil;
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
[downloadWrapper setDelegate:nil];
}
就这么简单。这有望模仿记录在案的cancel 方法,该方法指出它执行以下操作:
一旦调用此方法,接收者的委托将不再 接收此 NSURLConnection 的任何消息。
我担心这种(有点幼稚的)方法意味着数据包仍然会通过响应我们的 URL 请求——只是我们不再作为代理“监听”。但后来我意识到,一旦发送了 URL 请求,就真的无法阻止响应返回给我们——我们只能忽略它(如果不在这个级别,那么仍然在网络层次结构中的某个较低级别) .如果我错了,请纠正我。
无论如何,希望这会有所帮助。
【讨论】:
似乎没有什么好的方法可以做到这一点。解决方案似乎是在需要取消请求的情况下不使用新的[NSURLConnection sendAsynchronousRequest]。
【讨论】: