我正在进行NSURLConnection,只有在有新文件时才会下载文件(使用上次修改日期进行检查)。但要实现这一点,我使用两种不同的NSURLRequests和NSURLConnection方法。嗯,他们做同样的事情。
- (IBAction)uppdatera:(id)sender
{
checkHeaders = YES;
NSURLRequest *theRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.forellgatan.se/site/ftp_files/Kapareskolan.zip"] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:10.0];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if (theConnection)
{
self.receivedData = [[NSMutableData data] retain];
}
else
{
UIAlertView *connectFailMessage = [[UIAlertView alloc] initWithTitle:@"Ingen internetanslutning! 1" message:@"Anslut dig till internet för att ladda ner!" delegate: self cancelButtonTitle:@"Ok" otherButtonTitles: nil];
[connectFailMessage show];
[connectFailMessage release];
}
}
- (void)downloadNewFile
{
NSURLRequest *theRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.forellgatan.se/site/ftp_files/Kapareskolan.zip"] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:10.0];
NSURLConnection *theConnection2 = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if (theConnection2)
{
self.receivedData = [[NSMutableData data] retain];
}
else
{
UIAlertView *connectFailMessage = [[UIAlertView alloc] initWithTitle:@"Ingen internetanslutning! 2" message:@"Anslut dig till internet för att ladda ner!" delegate: self cancelButtonTitle:@"Ok" otherButtonTitles: nil];
[connectFailMessage show];
[connectFailMessage release];
}
checkHeaders = NO;
self.progressView.hidden = NO;
}
它通过didReceiveResponse方法:
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
if (checkHeaders == YES)
{
NSHTTPURLResponse *test = (NSHTTPURLResponse *)response;
if ([test respondsToSelector:@selector(allHeaderFields)])
{
NSDictionary *metaData = [test allHeaderFields];
NSString *lastModifiedString = [metaData objectForKey:@"Last-Modified"];
NSString *savedString = [[NSUserDefaults standardUserDefaults] stringForKey:@"LastModified"];
if (![lastModifiedString isEqualToString:savedString])
{
[self downloadNewFile];
}
else if ([lastModifiedString isEqualToString:savedString])
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Ingen uppdatering tillgänglig" message:@"Det finns ingen uppdatering att hämta just nu." delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil];
[alert show];
[alert release];
}
NSUserDefaults *standardUserDefaults = [NSUserDefaults standardUserDefaults];
[standardUserDefaults setObject:lastModifiedString forKey:@"LastModified"];
[standardUserDefaults synchronize];
}
}
[self.receivedData setLength:0];
self.fileSize = [[NSNumber numberWithLong: [response expectedContentLength]] retain];
}
最后的connectionDidFinishLaunching方法:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
if (checkHeaders == NO)
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *basePath = ([paths count] > 0) ? [paths objectAtIndex:0] : nil;
[self.receivedData writeToFile:[basePath stringByAppendingPathComponent:@"Kapareskolan.zip"] atomically:YES];
[self unzipDownloadedFile];
self.progressView.hidden = YES;
NSLog(@"Finished...");
}
[connection cancel];
}
我知道didFinishLaunching方法会被调用两次,但是我想知道如何进行,所以如果有更新,方法不会被调用两次?
我知道这里有很多问题和很多代码,但只是给我一个提示,我会非常感激。
答案 0 :(得分:2)
如果您已经完成了didReceiveResponse方法中的第一个连接对象,那么您应该取消它。否则它将进入connectionDidFinishLoading方法。 我想这就是你想要的:
if (![lastModifiedString isEqualToString:savedString])
{
[connection cancel];
[self downloadNewFile];
}
此外,看起来您在启动第二个请求后将checkHeaders设置为NO,这可能会导致竞争条件。
答案 1 :(得分:1)
根据programming guide,在委托收到connectionDidFinishLoading:或connection:didFailWithError:message之前,可以通过向连接发送取消消息来随时取消连接“。
所以为什么不尝试移动
[connection cancel];
从connectionDidFinishLoading
方法到if-else
委托方法中的didReceiveResponse
块之后?您希望在任何一种情况下取消“checkHeaders == YES”连接;或者您要开始新的连接,或者您已经知道当前连接需要知道的所有内容。
按要求更新:
if (![lastModifiedString isEqualToString:savedString]) {
[self downloadNewFile];
} else { // you've already implicitly checked for equality above
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Ingen uppdatering tillgänglig" message:@"Det finns ingen uppdatering att hämta just nu." delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil];
[alert show];
[alert release];
}
// you've used the connection for everything that you need, so cancel it in either case
[connection cancel];
当downloadNewFile
异步启动NSURLConnection
时,如果两个字符串相等,这应该没问题。稍微更安全的是将cancel
方法调用移到if-else
检查之前。