我在tableview单元子类中有一个NSURLConnection
,可以下载大多数文件。但是,我注意到有些人无法开始下载,并且超时。一个例子是this URL,它只是一个可以在任何其他浏览器中正常下载的测试zip文件。下面是我的下载代码
-(void)downloadFileAtURL:(NSURL *)url{
self.downloadedData = [[NSMutableData alloc] init];
self.url = url;
conn = [[NSURLConnection alloc] initWithRequest:[NSURLRequest requestWithURL:self.url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:1200.0] delegate:self startImmediately:YES];
}
- (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSHTTPURLResponse*)response
{
int statusCode = [response statusCode];
if (statusCode == 200){
self.fileName.text = response.URL.lastPathComponent;
self.respo = response;
expectedLength = [response expectedContentLength];
}
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
[self.downloadedData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
CFStringRef mimeType = (__bridge CFStringRef)[_respo MIMEType];
CFStringRef uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassMIMEType, mimeType, NULL);
CFStringRef extension = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassFilenameExtension);
NSString *fileName = [NSString stringWithFormat:@"%@.%@", [[_respo suggestedFilename] stringByDeletingPathExtension], (__bridge NSString *)extension];
[[NSFileManager defaultManager] createFileAtPath:[[self docsDir] stringByAppendingPathComponent:[NSString stringWithFormat:@"Downloads/%@", fileName]] contents:_downloadedData attributes:nil];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
NSLog(@"Download failed with error: %@", error);
}
有人看到任何可能导致这种情况的事吗?
继承错误:
Error Domain=NSURLErrorDomain Code=-1001 "The request timed out." UserInfo=0x1fd2c650
{NSErrorFailingURLStringKey=http://download.thinkbroadband.com/10MB.zip,
NSErrorFailingURLKey=http://download.thinkbroadband.com/10MB.zip,
NSLocalizedDescription=The request timed out., NSUnderlyingError=0x1fdc90b0 "The request timed out."}
答案 0 :(得分:3)
“我在tableview单元子类中有一个NSURLConnection” - 永远不要这样做。正如Sung-Pil Lim已正确指出的那样,TableView Cells将被重用,这可能会导致此问题。
无论如何,您的连接的响应数据是模型的属性。该模型可能会封装它如何获取此数据。如果该数据一旦被访问就不能立即获得,它应该提供一个“占位符”值,并启动一个异步任务来检索这些数据。
假设视图控制器将访问模型的属性(图像),以便由视图显示。该模型尚未加载其实际图像 - 因此它返回“占位符图像”以便让视图显示某些内容。但与此同时,模型正在启动异步任务来加载图像。当此连接完成加载数据时,模型会在内部更新其属性 - 从而用实际图像替换占位符。应该在主线程上执行属性的更新 - 因为UIKit视图也可以访问相同的属性。
在初始化期间,View Controller已注册为模型属性的观察者(请参阅KVO)。更新模型的属性后,控制器会收到通知。然后,View Controller将执行适当的操作,以便重新绘制视图并显示新的更新值。
您的模型应该有一个“取消”方法,当不再需要模型属性的实际值时,该方法将从控制器发送到模型。例如,用户切换到另一个视图(请参阅viewWillDisappear)。
答案 1 :(得分:2)
我尝试了你的代码。
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
[self.downloadedData appendData:data];
NSLog(@"%d", data.length);
}
2013-05-04 01:51:13.811 SomethingTodo[2732:c07] 1124
2013-05-04 01:51:13.856 SomethingTodo[2732:c07] 1448
2013-05-04 01:51:14.075 SomethingTodo[2732:c07] 1448
2013-05-04 01:51:17.180 SomethingTodo[2732:c07] 1448
2013-05-04 01:51:17.295 SomethingTodo[2732:c07] 1448
它正在ViewController
上工作'请求超时错误'被带到网络连接。或...
您是否正在重新使用UITableViewCell?如果初始化单元重用代码处理连接。也许会带来麻烦。只是我想。
如果您附加更多代码。我可以帮助你吗?
答案 2 :(得分:0)
我会从一个干净的平板开始,只需使用基本代码来完成下载。加载许多NSLog以跟踪所有内容。如果可行,请继续添加自定义代码,看看是否偶然发现错误。我建议使用基本的NSURLConnection代码:
-(void)startDownloading:(NSString *)URLaddress{
NSLog(@"start downloading from: %@",URLaddress);
NSURLRequest *theRequest=[NSURLRequest requestWithURL:[NSURL URLWithString:[URLaddress stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
__unused NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:theRequest delegate:self startImmediately:YES];
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
NSLog(@"didReceiveResponse: %@", response);
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
NSLog(@"didReceiveData");
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
NSLog(@"Connection failed! Error - %@ %@",[error localizedDescription], [[error userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]);
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
NSLog(@"connectionDidFinishLoading");
}
答案 3 :(得分:0)
尝试使用HCDownloadViewController,您可以检查未下载的网址。以及下次未同步的特定网址的同步。
.h文件
#import "HCDownloadViewController.h"
@interface HomeViewController_iPhone : UIViewController<HCDownloadViewControllerDelegate>
{
HCDownloadViewController *tblDownloadHairStyle;
}
@property (nonatomic,retain) HCDownloadViewController *tblDownloadHairStyle;
.m文件
#define kAppDirectoryPath NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)
@synthesize tblDownloadHairStyle
- (void)viewDidLoad
{
[super viewDidLoad];
tblDownloadHairStyle=[[HCDownloadViewController alloc] init];
tblDownloadHairStyle.delegate=self;
}
- (void)connection:(NSURLConnection*)connection didReceiveResponse:(NSHTTPURLResponse*)response
{
[self createDocumentDirectory:@"Downloaded_HairStyle"];
NSString *pathHair=[self getDocumentDirectoryPath:@"Downloaded_HairStyle"];
tblDownloadHairStyle.downloadDirectory = pathHair;
////You can put url in for loop, it create queue for downloading.
[tblDownloadHairStyle downloadURL:[NSURL URLWithString:@"yourUrl"] userInfo:YourResponseDictonary];
}
-(void)createDocumentDirectory:(NSString*)pStrDirectoryName
{
NSString *dataPath = [self getDocumentDirectoryPath:pStrDirectoryName];
if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath])
[[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:NULL];
}
-(NSString*)getDocumentDirectoryPath:(NSString*)pStrPathName
{
NSString *strPath = @"";
if(pStrPathName)
strPath = [[kAppDirectoryPath objectAtIndex:0] stringByAppendingPathComponent:pStrPathName];
return strPath;
}
#pragma mark-
#pragma mark-HCDownloadViewController Delegate Method
- (void)downloadController:(HCDownloadViewController *)vc startedDownloadingURL:(NSURL *)url userInfo:(NSDictionary *)userInfo {
}
- (void)downloadController:(HCDownloadViewController *)vc finishedDownloadingURL:(NSURL *)url toFile:(NSString *)fileName userInfo:(NSDictionary *)userInfo {
if (vc==tblDownloadHairStyle) {
if ([tblDownloadHairStyle numberOfDownloads]==0) {
NSLog(@"AllDownLoad are complete");
}
}
}
- (void)downloadController:(HCDownloadViewController *)vc failedDownloadingURL:(NSURL *)url withError:(NSError *)error userInfo:(NSDictionary *)userInfo {
NSLog(@"failedDownloadingURL=%@",url);
}
答案 4 :(得分:0)
接受http响应代码范围为200-299的任何响应,并禁用http连接器上的缓存。
答案 5 :(得分:-1)
仔细检查您的网址是否符合RFC 2396.所以它必须包含HTTP://
答案 6 :(得分:-1)
项目中是否有任何库(TestFlight,UA等)?尝试删除它们并重新测试。我们有一个应用程序使用NSUrlConnection和TestFlight SDK,导致各种零星的网络问题。