2014-10-22 107 views
0

我试图从网页缓存图像,以防止过多的网络请求,以节省电池和数据。其基本思想是:iOS - 缓存远程图像

  1. 生成该文件的位置
  2. 的字符串如果该文件存在,那么从文件加载
  3. 如果它不存在(TODO:或者如果该文件是不是旧的一天),然后从网上下载图像。保存并加载它。

但是我的代码不工作,我不明白为什么?

// imagesFileName has been correctly generated as as imageURL 
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, 
                NSUserDomainMask, YES); 
NSString *documentsDirectory = [paths objectAtIndex:0]; 
NSString *imagesLibraryPath = [documentsDirectory stringByAppendingPathComponent:@"Images"]; 
NSString *imagePath = [imagesLibraryPath stringByAppendingPathComponent:imageFileName]; 


// Do We Have the icon in cache? 
if (![[NSFileManager defaultManager] fileExistsAtPath:iconPath]) { 
    // File Doesn't Exist - Load Image From URL 
    NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:imagesURL]]; 

    // Save Image 
    [imageData writeToFile:imagePath atomically:YES]; 


    NSLog(@"Downloading & Importing Image"); 
    return [UIImage imageWithData:imageData]; 
} else { 
    // Load the Image From The File But Update If Needed 
    NSLog(@"Loading Image From Cache"); 
    return [UIImage imageWithContentsOfFile:imagePath]; 
} 
+0

在哪种情况下你有麻烦?从读取缓存或写入缓存? – l0gg3r 2014-10-22 09:22:12

+1

你的'if'语句检查'iconPath'是否存在,但我认为你的意思是'imagePath'?你的'NSData'调用然后从'imagesURL'创建一个URL,我认为它应该是'imagePath'。另外,如果你正在缓存数据,你应该把它放在'Library/Caches'文件夹('NSCachesDirectory')中,这样操作系统可以在空间不足时删除这些数据,因为它可以被你的应用程序重新下载。将其放置在Caches文件夹中也可以确保它不会被iTunes和iCloud自动备份。 – ttarik 2014-10-22 09:29:09

+0

@ ev0lution我改变了iconPath到imagePath,那只是一个错字。 imageURL引用Web上的URL来抓取图像,而imagePath引用保存的(缓存的)文件位置。我如何获取应用程序的缓存目录? – dgee4 2014-10-22 11:25:45

回答

1

有一些问题在这里,但首先,你有没有什么方式你的代码是行不通的说。如果您提供更多信息,也许我们可以提供更多帮助

我不会推荐使用NSDatadataWithContentsOfURL:。此方法同步加载数据(当前函数中的代码执行停止,直到完成)。此方法通常应仅用于本地文件(使用file:// URL方案),而不适用于远程URL。查看与NSURLSessionNSURLConnection异步加载数据,并阅读Apple的URL Loading System Programming Guide

URL加载系统内置了对缓存的支持,所以您应该尽可能使用它,并完全放弃此代码。请阅读URL加载系统编程指南以及NSURLCache article on HSHipster中的Understanding Cache Access

如果你想编写自己的缓存系统(我不推荐),则至少:

  • 使用缓存目录,而不是文件目录(见ev0lution的评论)。
  • 避免NSFileManagerfileExistsAtPath:(见the note in the documentation)。请尝试从磁盘加载映像并查看是否失败(返回nil)。
+0

我可以使用iOS缓存吗?链接将我转发到Mac OS X开发人员网站?你能举一个例子来说明如何创建这样的缓存并检索和下载数据? – dgee4 2014-10-22 11:27:49

+0

URL加载系统在iOS和OS X上几乎完全相同。无论如何,我已将链接更改为iOS文档。 – 2014-10-22 12:55:37

0

在else部分中,您只是返回图像位置路径。在这里你需要传递图像名称与该路径。

所以你else部分应该是这样的

else { 
     // Load the Image From The File But Update If Needed 
     NSLog(@"Loading Image From Cache"); 
     // e.g Some image name 
     NSString *imageName = @"Image1.png"; 
     [imagePath stringByAppendingPathComponent:imageName]; 
     return [UIImage imageWithContentsOfFile:imagePath]; 
    }