What's the default cache expiration time for NSURLRequests?
Asked Answered
Z

3

8

I'm using a NSURLRequest to check for available data updates. Today I noticed, that NSURLRequest caches the request by default. Even after several hours no new request was sent to the server. Now I'm wondering what the default behavior of this cache is. When will the cached data be stale and a new request send to the server? The data is a static file and the server does not send explicit cache control headers:

HTTP/1.1 200 OK
Date: Fri, 13 Apr 2012 08:51:13 GMT
Server: Apache
Last-Modified: Thu, 12 Apr 2012 14:02:17 GMT
ETag: "2852a-64-4bd7bcdba2c40"
Accept-Ranges: bytes
Content-Length: 100
Vary: Accept-Encoding,User-Agent
Content-Type: text/plain

P.S.: The new version of my app sets an explicit caching policy, so that this isn't a problem anymore, but I'm curious what the default behavior is.

Zeigler answered 13/4, 2012 at 9:8 Comment(0)
L
15

Note: here specifies how this should work in detail

  1. If there is no cache then fetch the data.

  2. If there is a cache, then check the loading scheme

    a. if re-validation is specified, check the source for changes

    b. if re-validation is not specified then fetch from the local cache as per 3)

  3. If re-validation is not specified the local cache is checked to see if it is recent enough.

    a. if the cache is not stale then it pulls the data from the cache

    b. if the data is stale then it re-validates from the source

From here:

The default cache policy for an NSURLRequest instance is NSURLRequestUseProtocolCachePolicy. The NSURLRequestUseProtocolCachePolicy behavior is protocol specific and is defined as being the best conforming policy for the protocol

From here:

If an NSCachedURLResponse does not exist for the request, then the data is fetched from the originating source. If there is a cached response for the request, the URL loading system checks the response to determine if it specifies that the contents must be revalidated. If the contents must be revalidated a connection is made to the originating source to see if it has changed. If it has not changed, then the response is returned from the local cache. If it has changed, the data is fetched from the originating source.

If the cached response doesn’t specify that the contents must be revalidated, the maximum age or expiration specified in the response is examined. If the cached response is recent enough, then the response is returned from the local cache. If the response is determined to be stale, the originating source is checked for newer data. If newer data is available, the data is fetched from the originating source, otherwise it is returned from the cache.

Other options listed here.

Leela answered 16/4, 2012 at 12:54 Comment(11)
Thanks for your answer. I have read the documentation. It states, that the "behavior is protocol specific". Now, if now explicit expiration time is set by the server and no specific behavior is configured on the client side, after which time will NSUrlRequest evict items from the cache?Zeigler
As far as I can tell, the NSUrlCache has no time limit. The time limit is set by the request protocol. If the protocol doesn't specify one, there probably isn't one.Leela
This would be pretty stupid. Think of my case: You would never get up-to-date data after the initial request. But you might be right, since iOS didn't send a new request even after hours. Only a restart of the device helped.Zeigler
It's my understanding that particular pages can specify their expiration date. Additionally, the particular application has a finite cache size and when that is exceeded then older data is removed.Leela
Right. In my case I have an apache web server running, which sends a plain text file with information about the available data updates. This file is very small and loaded only once a day, so it might take years until the cache is full and old files get evicted.Zeigler
Also, if there is no information about when the data is stale, I would check for new data every time instead of never. This default behavior of iOS is weird.Zeigler
It probably means they expect you to set the caching behavior. In your case NSURLRequestReloadRevalidatingCacheData probably makes more sense.Leela
I have changed the code to use NSURLRequestReloadIgnoringCacheData for this update check already. Nevertheless evicting data after 5 or 10 mins or even checking every time would be a much better default behavior, if no information about the epiration date is available.Zeigler
The eviction time probably changes from application to application which is why they force you to specify. I agree some sort of auto-revalidation would be nice.Leela
What does it mean to "check the loading scheme?" Is the loading scheme something the programmer can specify? ThanksRedfaced
@Redfaced It's been quite some time since I did the research for this post, but if I remember correctly that would probably be better as "check the loading policy" but it's been awhile so I'm just going to leave this as a comment rather than modifying my answer. As such, I think it's specified (by the developer) server-side.Leela
T
0

It used to do a fresh request after i restart my app. By restart, i do it by pressing home button twice which shows list of running apps, kill my app and do a fresh start again by clicking on app icon.

Also it is possible to disable caching if you want to. override this method of NSURLProtocol delegate

//disable caching since our files are stored in multiple servers and false response caching can cause issues.

-(NSCachedURLResponse *)connection:(NSURLConnection *)connection
                 willCacheResponse:(NSCachedURLResponse *)cachedResponse
{
    NSCachedURLResponse *newCachedResponse = cachedResponse;

    //if ([[[[cachedResponse response] URL] scheme] isEqual:@"https"]) 
    {
        newCachedResponse = nil;
    } 
    return newCachedResponse;
}
Tolu answered 13/4, 2012 at 10:25 Comment(2)
I know how to solve this problem. I mentioned, that I set an explicit caching policy in the new version of my app. So, the actual problem is resolved. I'm just curious about the default behavior.Zeigler
I just based answer on my callbacks, If i look at my logs applicationWIllTerminate gets called whenever i do a remove from multitask list, which is why i believe it for app developer this is where u need to handle app quit code. I wanted to indicate that cache gets refresh once app is launched freshly after thisTolu
C
0

According to this article: http://blackpixel.com/blog/2012/05/caching-and-nsurlconnection.html , if you are using NSURLRequestUseProtocolCachePolicy and the server does not return either expiration or max-age, the default cache time interval is 6 - 24 hours. So Be careful about this condition. It is a better practice to set max-age or expiration when using NSURLRequestUseProtocolCachePolicy.

Caravansary answered 22/4, 2014 at 8:47 Comment(1)
Currently using NSURLRequestUseProtocolCachePolicy does not automatically mean that something will be cached, I tried it a moment ago.Anneal

© 2022 - 2024 — McMap. All rights reserved.