iOS 服务器文件有修改才进行下载

来源:互联网 发布:同济大学软件研究生 编辑:程序博客网 时间:2024/05/01 00:19

当要下载的文件会定期修改,而且比较大时,可以在文件有修改的时候,才进行下载。


有两种方式

一、需要服务器支持304状态码(推荐

请求中带上 If-Modified-Since 字段,如果在这个时间后,文件有修改,则返回200状态码,以及文件内容。如果文件没有修改,则返回304状态码,文件内容不会返回

+(void)downloadFileIfUpdatedWithLocalPath:(NSString*)path url:(NSString*)urlStr{    if(path.length == 0 || urlStr.length == 0)        return;        // 保存文件最后修改时间的Key    NSString *lastModifyKey = KeyLastModify([urlStr MD5]);    // 获取上次得到的文件最后修改时间    NSString *lastModifyLocal = [[NSUserDefaults standardUserDefaults] objectForKey:lastModifyKey];        NSURL *url = [NSURL URLWithString:urlStr];    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];    [request setHTTPMethod:@"GET"];    [request setValue:lastModifyLocal forHTTPHeaderField:@"If-Modified-Since"];        NSURLSessionDownloadTask *task = [[NSURLSession sharedSession] downloadTaskWithRequest:request completionHandler:^(NSURL * _Nullable location, NSURLResponse * _Nullable response, NSError * _Nullable error) {                if(!error)        {            NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;                        if(httpResponse.statusCode == 200)            {                NSFileManager *fileManager = [NSFileManager defaultManager];                                NSString *fileDir = [path stringByDeletingLastPathComponent];                if(![fileManager fileExistsAtPath:fileDir])                {                    // 创建目录                    [fileManager createDirectoryAtPath:fileDir withIntermediateDirectories:YES attributes:nil error:nil];                }                                NSData *fileData = [NSData dataWithContentsOfURL:location];                if ([fileData writeToFile:path atomically:YES])                {                    // 存储文件的最后修改时间                    NSString *lastModifyServer = [[httpResponse allHeaderFields] objectForKey:@"Last-Modified"];                    [[NSUserDefaults standardUserDefaults] setObject:lastModifyServer forKey:lastModifyKey];                }                            }            else if(httpResponse.statusCode == 304)            {                NSLog(@"无需更新%@",[path lastPathComponent]);            }                    }            }];        [task resume];}


二、不需要服务器支持304状态码

1、通过HEAD请求获取文件的最后修改时间

2、与本地存储的文件最后修改时间进行比较

3、如果有更新,则直接请求文件

下面方法需要放到异步队列中执行,否则会阻塞主线程

+(void)downloadFileIfUpdatedWithLocalPath:(NSString*)path url:(NSString*)urlStr{    BOOL download = NO;    NSURL *url = [NSURL URLWithString:urlStr];    NSDate *lastModifiedLocal = nil;    NSDate *lastModifiedServer = nil;    // 询问服务器是否有修改    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];    [request setHTTPMethod:@"HEAD"];    NSHTTPURLResponse *response;    [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:NULL];    if ([response respondsToSelector:@selector(allHeaderFields)]) {        NSString *lastModifiedString = [[response allHeaderFields] objectForKey:@"Last-Modified"];        NSDateFormatter *df = [[NSDateFormatter alloc] init];        df.dateFormat = @"EEE',' dd MMM yyyy HH':'mm':'ss 'GMT'";        df.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];        df.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];        lastModifiedServer = [df dateFromString:lastModifiedString];    }    // 查看本地存储    NSFileManager *fileManager = [NSFileManager defaultManager];    if ([fileManager fileExistsAtPath:path]) {        NSError *error = nil;        NSDictionary *fileAttributes = [fileManager attributesOfItemAtPath:path error:&error];        lastModifiedLocal = [fileAttributes fileModificationDate];    }    if (!lastModifiedLocal || [lastModifiedLocal laterDate:lastModifiedServer] == lastModifiedServer) {        download = YES;    }    if(download)    {        NSData *data = [NSData dataWithContentsOfURL:url];        if (data)        {            NSString *dirPath = [path stringByDeletingLastPathComponent];            NSError *error = nil;            if(![fileManager fileExistsAtPath:dirPath])            {                [fileManager createDirectoryAtPath:dirPath withIntermediateDirectories:YES attributes:nil error:&error];            }            if ([data writeToFile:path atomically:YES])            {                NSLog(@"Downloaded file saved to: %@", path);            }            if (lastModifiedServer)            {                NSDictionary *fileAttributes = [NSDictionary dictionaryWithObject:lastModifiedServer forKey:NSFileModificationDate];                if ([fileManager setAttributes:fileAttributes ofItemAtPath:path error:&error]) {                    NSLog(@"File modification date updated");                }                if (error) {                    NSLog(@"Error setting file attributes for: %@ - %@", path, [error localizedDescription]);                }            }        }    }}


比较

方式一:

1、不管文件是否需要更新,都只有一次请求;

2、最后修改时间的比较,都由服务器处理,App无需关心时间的格式


方式二:

1、文件不需要更新时,只有一次请求。文件需要更新时,一共有两次请求;

2、最后修改时间由App比较,需要关心时间格式。一旦时间格式改变,就会有问题




0 0