如何使用NSURLSession和NSURLCache进行缓存。不工作 [英] How to cache using NSURLSession and NSURLCache. Not working

查看:152
本文介绍了如何使用NSURLSession和NSURLCache进行缓存。不工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个测试应用程序设置,即使用户在下载过程中切换应用程序,它也能成功从网络下载内容。好的,现在我已经有了后台下载。现在我想添加缓存。没有必要让我多次下载图像,b / c系统设计,给定一个图像URL我可以告诉你该URL后面的内容永远不会改变。所以,现在我想使用我内置的内置/磁盘缓存来缓存我的下载结果,我已经阅读了很多(而不是我在NSCachesDirectory中手动保存文件,然后在创建之前检查文件)请求,ick)。在尝试以使缓存在此工作代码之上工作时,我添加了以下代码:

I have a test app setup and it successfully downloads content from the network even if the user switches apps while a download is in progress. Great, now I have background downloads in place. Now I want to add caching. There is no point to me downloading images more than once, b/c of system design, given an image URL I can tell you the content behind that URL will never change. So, now I want to cache the results of my download using apple's built in in-memory/on-disk cache that I've read so much about (as opposed to me saving the file manually in NSCachesDirectory and then checking there before making new request, ick). In an attempt to get caching working on top of this working code, I added the following code:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Override point for customization after application launch.

    // Set app-wide shared cache (first number is megabyte value)
    [NSURLCache setSharedURLCache:[[NSURLCache alloc] initWithMemoryCapacity:60 * 1024 * 1024
                                                                diskCapacity:200 * 1024 * 1024
                                                                    diskPath:nil]];

    return YES;
}

当我创建会话时,我添加了两行NEW(URLCache和requestCachePolicy)。

When I create my session, I've added two NEW lines (URLCache and requestCachePolicy).

// Helper method to get a single session object
- (NSURLSession *)backgroundSession
{
    static NSURLSession *session = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfiguration:@"com.example.apple-samplecode.SimpleBackgroundTransfer.BackgroundSession"];
        configuration.URLCache = [NSURLCache sharedURLCache]; // NEW LINE ON TOP OF OTHERWISE WORKING CODE
        configuration.requestCachePolicy = NSURLRequestReturnCacheDataElseLoad;  // NEW LINE ON TOP OF OTHERWISE WORKING CODE
        session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
    });
    return session;
}

然后,为了看到缓存成功我只需要超冗余我的NSURLRequest行来自

Then, just to be ultra redundant in an attempt to see caching success I switched my NSURLRequest line from

// NSURLRequest *request = [NSURLRequest requestWithURL:downloadURL]; // Old line, I've replaced this with...
NSURLRequest *request = [NSURLRequest requestWithURL:downloadURL cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:2*60]; // New line

现在,当我第二次下载该项目时,体验非常好像第一个!!需要很长时间才能下载和进度条动画缓慢而稳定,就像原始下载一样。我想立即在缓存中的数据!!我错过了什么???

Now, when I go to download the item a 2nd time, the experience is exaclty like the first!! Takes a long time to download and progress bar is animated slow and steady like an original download. I want the data in the cache immediately!! What am I missing???

----------------------------更新----------------------------

----------------------------UPDATE----------------------------

好的,感谢Thorsten的回答,我已经将以下两行代码添加到我的 didFinishDownloadingToURL 委托方法中:

Okay, thanks to Thorsten's answer, I've added the following two lines of code to my didFinishDownloadingToURL delegate method:

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)downloadURL {

    // Added these lines...
    NSLog(@"DiskCache: %@ of %@", @([[NSURLCache sharedURLCache] currentDiskUsage]), @([[NSURLCache sharedURLCache] diskCapacity]));
    NSLog(@"MemoryCache: %@ of %@", @([[NSURLCache sharedURLCache] currentMemoryUsage]), @([[NSURLCache sharedURLCache] memoryCapacity]));
    /*
    OUTPUTS:
    DiskCache: 4096 of 209715200
    MemoryCache: 0 of 62914560
    */
}

这很棒。它证实缓存正在增长。我认为,因为我使用的是downloadTask(下载到文件而不是内存),这就是为什么DiskCache正在增长而不是内存缓存?我想一切都会进入内存缓存,直到溢出,然后使用磁盘缓存,并且可能在操作系统在后台杀死应用程序以释放内存之前,内存缓存被写入磁盘。我是否误解了Apple的缓存是如何工作的?

This is great. It confirms the cache is growing. I presume since I'm using a downloadTask (downloads to file as opposed to memory), that that's why DiskCache is growing and not memory cache first? I figured everything would go to memory cache until that overflowed and then disk cache would be used and that maybe memory cache was written to disk before the OS kills the app in the background to free up memory. Am I misunderstanding how Apple's cache works?

这是向前迈出的一步,但第二次下载文件它只需要第一次时间(可能是10秒左右)并且以下方法再次执行:

This is a step forward for sure, but the 2nd time I download the file it takes just as long as the first time (maybe 10 seconds or so) and the following method DOES get executed again:

- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite
{
    // This shouldn't execute the second time around should it? Even if this is supposed to get executed a second time around then shouldn't it be lightning fast? It's not.
    // On all subsequent requests, it slowly iterates through the downloading of the content just as slow as the first time. No caching is apparent. What am I missing?
}

您对我上面的编辑有何看法?为什么我在后续请求中没有看到文件很快返回?

What do you make of my edits above? Why am I not seeing the file returned very quickly on subsequent requests?

如何在第二次请求时确认文件是否从缓存中提供?

How can I confirm if the file is being served from the cache on the 2nd request?

推荐答案

请注意以下SO帖子帮助我解决了我的问题: NSURLCache在启动时是否持续存在?

Note that the following SO post helped me solve my problem: Is NSURLCache persistent across launches?

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Set app-wide shared cache (first number is megabyte value)
    NSUInteger cacheSizeMemory = 500*1024*1024; // 500 MB
    NSUInteger cacheSizeDisk = 500*1024*1024; // 500 MB
    NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:cacheSizeMemory diskCapacity:cacheSizeDisk diskPath:@"nsurlcache"];
    [NSURLCache setSharedURLCache:sharedCache];
    sleep(1); // Critically important line, sadly, but it's worth it!
}

除了 sleep(1)行,还要注意我的缓存大小; 500MB。您需要的缓存大小比您尝试缓存的大小要大。因此,例如,如果您希望能够缓存10MB图像,那么10MB甚至20MB的缓存大小是不够的。如果你需要能够缓存10MB,我建议使用100MB缓存。希望这可以帮助!!为我做了诀窍。

In addition to the sleep(1) line, also note the size of my cache; 500MB. You need a cache size that is way bigger than what you're trying to cache. So for example if you want to be able to cache a 10MB image, then a cache size of 10MB or even 20MB will not be enough. If you need to be able to cache 10MB I'd recommend a 100MB cache. Hope this helps!! Did the trick for me.

这篇关于如何使用NSURLSession和NSURLCache进行缓存。不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆