【问题标题】:iOS - Download file only if modified (NSURL & NSData)iOS - 仅在修改后下载文件(NSURL 和 NSData)
【发布时间】:2012-12-01 17:17:07
【问题描述】:

我正在从服务器下载一堆图像文件,我想确保仅在它们较新时才下载它们。 此方法目前可以​​很好地下载图像。但是,我不想每次用户登录应用程序时都浪费时间或精力重新下载图像。相反,我只想下载 A) 不存在 B) 在服务器上比在设备上更新的任何文件

这是我下载图像的方式: *图像 url 与关联的视频一起保存在 Core Data 中。 url是使用我构建的简单转换方法生成的(generateThumbnailURL)

-(void)saveThumbnails{
    NSManagedObjectContext *context = [self managedObjectContextThumbnails];
    NSError *error;
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription
                                   entityForName:@"Videos" inManagedObjectContext:context];
    [fetchRequest setEntity:entity];
    NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
    NSLog(@"Videos: %i",fetchedObjects.count);
    if (fetchedObjects.count!=0) {
        for(Videos *currentVideo in fetchedObjects){
            // Get an image from the URL below
            NSURL *thumbnailURL = [self generateThumbnailURL:[currentVideo.videoID intValue]];

            UIImage *image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfURL:thumbnailURL]];

            // Let's save the file into Document folder.
            // You can also change this to your desktop for testing. (e.g. /Users/kiichi/Desktop/)
            NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);//Find Application's Document Directory
            NSString *documentsDirectory = [paths objectAtIndex:0];
            NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:@"DownloadedThumbnails"];
            //        NSString *dataPath = @"/Users/macminidemo/Desktop/gt";//DEBUG SAVING IMAGE BY SAVING TO DESKTOP FOLDER

            //Check if Sub-directory exists, if not, try to create it
            if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath]){
                NSError* error;
                if([[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:&error]){
                    NSLog(@"New Folder Created!");
                }
                else
                {
                    NSLog(@"[%@] ERROR: attempting to write create new directory", [self class]);
                    NSAssert( FALSE, @"Failed to create directory maybe out of disk space?");
                }
            }
            NSArray *splitFilename = [[self generateThumbnailFilename:[currentVideo.videoID intValue]] componentsSeparatedByString:@"."];//Break Filename Extension Off (not always PNGs)
            NSString *subString = [splitFilename objectAtIndex:0];
            NSString *formattedFilename = [NSString stringWithFormat:@"%@~ipad.png",subString];
            NSString *localFilePath = [dataPath stringByAppendingPathComponent:formattedFilename];
            NSData *imageData = [NSData dataWithData:UIImagePNGRepresentation(image)];
            [imageData writeToFile:localFilePath atomically:YES];
            NSLog(@"Image: %@ Saved!",formattedFilename);
        }
    }
}

【问题讨论】:

    标签: ios uiimage download nsdata nsurl


    【解决方案1】:

    我最终使用这种方法来检测文件上的修改日期: *发现于HERE

    -(bool)isThumbnailModified:(NSURL *)thumbnailURL forFile:(NSString *)thumbnailFilePath{
        // create a HTTP request to get the file information from the web server
        NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:thumbnailURL];
        [request setHTTPMethod:@"HEAD"];
    
        NSHTTPURLResponse* response;
        [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
    
        // get the last modified info from the HTTP header
        NSString* httpLastModified = nil;
        if ([response respondsToSelector:@selector(allHeaderFields)])
        {
            httpLastModified = [[response allHeaderFields]
                                objectForKey:@"Last-Modified"];
        }
    
        // setup a date formatter to query the server file's modified date
        // don't ask me about this part of the code ... it works, that's all I know :)
        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"];
    
        // get the file attributes to retrieve the local file's modified date
        NSFileManager *fileManager = [NSFileManager defaultManager];
        NSDictionary* fileAttributes = [fileManager attributesOfItemAtPath:thumbnailFilePath error:nil];
    
        // test if the server file's date is later than the local file's date
        NSDate* serverFileDate = [df dateFromString:httpLastModified];
        NSDate* localFileDate = [fileAttributes fileModificationDate];
    
        NSLog(@"Local File Date: %@ Server File Date: %@",localFileDate,serverFileDate);
        //If file doesn't exist, download it
        if(localFileDate==nil){
            return YES;
        }
        return ([localFileDate laterDate:serverFileDate] == serverFileDate);
    }
    

    【讨论】:

      【解决方案2】:

      如果您的服务器支持 HTTP 缓存,您可以使用 NSURLRequestReloadRevalidatingCacheData 指定您想要缓存的内容:

      NSURLRequest* request = [NSURLRequest requestWithURL:thumbnailURL cachePolicy:NSURLRequestReloadRevalidatingCacheData timeoutInterval:20];
      NSURLResponse* response;
      NSError* error;
      NSData* data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
      UIImage* image = [UIImage imageWithData:data];
      

      更多信息请阅读NSURLRequest documentation

      【讨论】:

      • 谢谢阿莱夫!我最终找到了另一种从服务器检测修改日期的方法。但是您的方法可能是更好的处理方法。我现在要审查它。谢谢!
      • 所以我只是尝试了这种方法,但它每次都下载图像。我的服务器确实启用了缓存(CentOS 上的 apache)。
      • 不幸的是,这不起作用,因为它没有实现(从 iOS 7.1 开始)。在 NSURLRequest.h 中它被标记为NSURLRequestReloadRevalidatingCacheData = 5, // Unimplemented
      • iOS10reloadIgnoringLocalAndRemoteCacheData & reloadRevalidatingCacheData 仍被标记为未实现...
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多