【问题标题】:How to increase expiry time of cache in AFNetworking for iOS如何在 AFNetworking for iOS 中增加缓存的到期时间
【发布时间】:2014-05-07 14:28:48
【问题描述】:

我需要下载并在单元格中显示图像,我正在使用

- (void)setImageWithURL:(NSURL *)url

这种方法,但一段时间后,下载的图像会从单元格中消失并再次下载。我发现图像只能在缓存中保存 30 秒,但我想将其永久保存在缓存中,并希望通过调用函数释放缓存来手动删除缓存。可能吗?

【问题讨论】:

  • 这是可能的。但它要求您将其存储在手机上,并在需要时从那里检索。顺便说一句,考虑到您的问题,您的问题的标题非常令人困惑。你可能想改变它。
  • 但是 AFNetworking API 中是否存在任何方法?
  • 您是否在表格视图单元格中设置图像?
  • 不,你必须自己写(这并不难)。
  • 并非如此。 AFNetworking 旨在从互联网检索数据。在您的应用程序生命周期内为您存储/缓存它不是他的责任。您可以保留 AFNetworking 库,您只需要自己添加文件的缓存/存储部分。当你想显示图像时,你只需先检查它是否在缓存中,如果没有,然后要求 AFNetworking API 延迟加载它(然后缓存/存储它。我可以给你一些代码,你可以在其中存储文件如果你愿意。这段代码将永久存储文件。

标签: ios caching afnetworking afnetworking-2


【解决方案1】:

NSURLCache 检查服务器标头以了解服务器的缓存策略以存储您的图像。还要确保您的缓存足够大以存储图像。如果图像大小大于 5%(或其他值),则不会缓存图像的缓存大小。

由于AFNetworking 使用默认的NSURLCache,您最好的选择是继承NSURLCache。使用 NSURLCache 的自定义版本,您可以检查请求是否为图像,如果是,则将其存储在您想要的时间到 caches 目录中的某个位置。

这样你就可以像以前一样继续使用AFNetworking。/

【讨论】:

  • 我认为 AFNetworking 已经在做,但不知道它存储图像的位置。看到这个--------------- (void)setImageWithURL:(NSURL )url placeholderImage:(UIImage *)placeholderImage { NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; [请求 addValue:@"image/" forHTTPHeaderField:@"Accept"];------------
  • 所有NSURLConnection/NSURLSession 使用NSURLCachce。由于 AFNetworking 建立在 NSURLConnection/NSURLSession 之上,因此他们使用 NSURLCache。因此,如果您的缓存太小,则不会缓存图像。如果您希望图像被缓存更长时间,那么服务器标头会告诉NSURLCache 它们应该被缓存,您将必须编写自己的NSURLCache 版本。
【解决方案2】:

这里获取图片的简单方法

- (void) cacheImage: (NSString *) ImageURLString
{
assert(nil != ImageURLString);

NSArray *myPathList = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *myPath    = [myPathList  objectAtIndex:0];
NSString * fileName = [ImageURLString lastPathComponent];
NSString * uniquePath = [myPath stringByAppendingPathComponent:fileName];
// Check for file existence
if(![[NSFileManager defaultManager] fileExistsAtPath: uniquePath])
{
    // Fetch image from url and cache it
    NSData *data = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString:ImageURLString]];
    [data writeToFile:uniquePath atomically:YES];
}

}

- (UIImage *) getCachedImage: (NSString *) ImageURLString
{
assert(nil != ImageURLString);

// create unique path for image
NSArray *myPathList = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *myPath    = [myPathList  objectAtIndex:0];
NSString * fileName = [ImageURLString lastPathComponent];
NSString * uniquePath = [myPath stringByAppendingPathComponent:fileName];

UIImage *image;

// Check for a cached version
if([[NSFileManager defaultManager] fileExistsAtPath: uniquePath])
{
    image = [UIImage imageWithContentsOfFile: uniquePath]; //this is the cached image
}
else
{
    // cache image and return cached image
    [self cacheImage: ImageURLString];
    image = [UIImage imageWithContentsOfFile: uniquePath];
}

return image;
}

通过调用第二种方法,您可以获得缓存的图像,如果没有缓存,它将从 URL 获取并将其存储在文件中并将图像返回给您。我没有为它实现清理代码。

【讨论】:

    【解决方案3】:

    使用 AFNetworking 检索文件时永久处理文件的一种好方法是使用以下方法:

    //Store the file
    + (void) cacheFile:(NSString *)fileName data:(NSData *)data
    {
        NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
        NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:fileName]; //add our image to the path
        NSFileManager *fileManager = [NSFileManager defaultManager];
        BOOL ok = [fileManager createFileAtPath:fullPath contents:data attributes:nil];
    
        if (!ok) {
            NSLog(@"Error creating file %@", fullPath);
        } else {
            NSFileHandle* myFileHandle = [NSFileHandle fileHandleForWritingAtPath:fullPath];
            [myFileHandle writeData:data];
            [myFileHandle closeFile];
        }
    }
    
    //Check if file is already stored
    + (BOOL) fileExistsInCache:(NSString *)fileName
    {
        NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
        NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:fileName];
    
        DLog(@"path to file's existance, %@", fullPath);
    
        return [[NSFileManager defaultManager] fileExistsAtPath:fullPath];
    }
    
    //Load file from storage
    + (NSData *) loadCachedFile:(NSString *)fileName
    {
        NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
        NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:fileName];
    
        DLog(@"path to file's existance, %@", fullPath);
    
        NSFileHandle* myFileHandle = [NSFileHandle fileHandleForReadingAtPath:fullPath];
        return [myFileHandle readDataToEndOfFile];
    }
    
    //Remove file from storage
    + (void) removeCachedFile:(NSString *)fileName
    {   
        NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
        NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:fileName];
    
        BOOL ok = [[NSFileManager defaultManager] removeItemAtPath:fullPath error:NULL];
    }
    
    //Find out what is already stored
    + (NSMutableArray *)returnAllCachedMediaFiles
    {
        NSString *documentsDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
        NSFileManager *fm = [NSFileManager defaultManager];
        NSArray *dirContents = [fm contentsOfDirectoryAtPath:documentsDirectory error:nil];
    
        DLog(@"dirContents %@", dirContents);
    
        NSMutableArray *cachedMediaFiles = [[[NSMutableArray alloc] init] autorelease];
    
        for (NSString *fileName in dirContents) 
        {
            if ([fileName hasSuffix:@".png"] || [fileName hasSuffix:@".jpg"]) 
            {
                [cachedMediaFiles addObject:fileName];
            }
        }
    
        return cachedMediaFiles;
    }
    

    我不能说您项目中的正确展示位置。但是,这些方法将为您提供足够的句柄来使用。 请记住,documentsDirectory 已被使用,您可能想要使用自己的东西(如 NSCachesDirectory 或其他)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-10-05
      • 2015-12-02
      • 1970-01-01
      • 2016-03-22
      • 2018-01-03
      • 2015-08-03
      • 1970-01-01
      相关资源
      最近更新 更多