Objective-c clear cache NSCachedURLResponse - ios

I ran this code because I think I am running into a caching issue:
NSCachedURLResponse *response = [[NSURLCache sharedURLCache] cachedResponseForRequest:request];
if(response){
NSLog(#"Got Response");
}else{
NSLog(#"No Response");
}
my question is how do I clear cache for the request URL ?

NSURLRequest has a cachePolicy property, which specifies the caching behaviour of the request.
Set the following cache policy NSURLRequestReloadIgnoringLocalCacheData when making the request like the example bellow will load the data from the url and not from the cache.
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:10];
NSURLRequestReloadIgnoringLocalCacheData
Specifies that the data for the URL load should be loaded from the
originating source. No existing cache data should be used to satisfy a
URL load request.
https://developer.apple.com/library/prerelease/mac/documentation/Cocoa/Reference/Foundation/Classes/NSURLRequest_Class/index.html#//apple_ref/c/tdef/NSURLRequestCachePolicy

Use removeCachedResponseForRequest: method of NSURLCache class.
Documentation link

Related

Load image with headers and cache it - Objective-C (macOS apps)

I need to load big image from thumbnail url with forHTTPHeaderField and cache it so that not to load again and again from url. Below is the code I am using.
NSString *urlStr = [NSString stringWithFormat:#"%#",medialurl];
NSURL *url = [NSURL URLWithString:urlStr];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setHTTPMethod:#"GET"];
[request setURL:url];
[request addValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request addValue:#"abcd" forHTTPHeaderField:#"ABC"];
[request addValue:#"xyzzy" forHTTPHeaderField:#"XYZ"];
[RestService fetchDataWithCompletionBlock:request completionHandler:^(NSData * _Nonnull responseData, NSURLResponse * _Nonnull response, NSError * _Nonnull error) {
NSString *responseStr = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSLog(#"responseStr: %#", responseStr);
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *) response;
long code = (long)[httpResponse statusCode];
NSLog(#"response status code: %ld", code);
completionBlock(responseData);
}];
Would setting a different cachePolicy on your request help?
request.cachePolicy = NSURLRequestReturnCacheDataElseLoad;
Use existing cache data, regardless or age or expiration date, loading from originating source only if there is no cached data.
There is a note on the cachePolicy property which states:
This property is ignored for requests used to construct NSURLSessionUploadTask and NSURLSessionDownloadTask objects, as caching is not supported by the URL Loading System for upload or download requests.
So, if that is how you're performing your request, this might not work and you would probably have to manage your caching for this request yourself.
You can check to see if there is a cached response for your request with the following (assuming you are using the shared cache and not creating your own):
NSCachedURLResponse* cachedResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:request];
if ( cachedResponse )
{
NSHTTPURLResponse* response = (NSHTTPURLResponse*)cachedResponse.response;
NSLog(#"Cached Response: %#", response.allHeaderFields);
}
else
{
NSLog(#"No Cached Response");
}
If your endpoint uses ETags, you can also store the value of the ETag header field from the cached response and then compare it to what you get back when you make your request, this would tell you if the response you get back was indeed from the cache or not.
If the above tells you there is no cached response for your request, then you'd have to look into why it might not be caching previous responses. Perhaps there is an issue with the "Cache-Control" header coming back from the server and you are not permitted to cache the responses? If that were the case and you have no control over the server side, you would have to use another method to cache your images.

how do I create a persistent Cache using UiWebView with objective-c?

I have a UIWebView when using the NSURLRequest I’m setting cachePolicy: NSURLRequestReturnCacheDataElseLoad and also setting the pro cache memory size. When I open the application with internet, I open the screens and then deactivate the internet, the url I open is cached, until then everything is fine, but when closing the application and open again it loses all the cache. Can you persist the cache?
I have this:
NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:500*1024*1024 diskCapacity:500*1024*1024 diskPath:nil];
[NSURLCache setSharedURLCache:sharedCache];
and loading from UIWebView:
NSURL *websiteURL = [NSURL URLWithString:URLString];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:websiteURL cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:60.0];
[self.mainWebView loadRequest:urlRequest];
I was able to resolve using a cache.manifest file on the server.

Local HTML Cache policy in UIWebView

I have walked through various solution to clear the local image cache in UIWebView, while i trying to load the image in html it atomically displays the previous image(i using the same name to replace the image in template).
[[NSURLCache sharedURLCache] removeAllCachedResponses];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]initWithURL:[NSURL fileURLWithPath:[[CustomFunctions getFilesPath] stringByAppendingPathComponent:obj]] cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:30.0];
[webview1 loadRequest:request];
[webview1 reload];
this is my code and can any one please suggest me to do this. Thanks in advance. sorry for my English.
//to prevent internal caching of webpages in application
NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:0 diskCapacity:0 diskPath:nil];
[NSURLCache setSharedURLCache:sharedCache];
//[sharedCache release];
sharedCache = nil;
try using this. It will clear the url cache memory of your application.
Try this ...
[[NSURLCache sharedURLCache] removeCachedResponseForRequest:NSURLRequest];
This would remove a cached response for a specific request. There is also a call that will remove all cached responses for all requests ran on the UIWebView:
[[NSURLCache sharedURLCache] removeAllCachedResponses];

NSURLCache does not work when response header value for transfer-encoding is chunked

I found an issue with (possibly) NSURLCache today while inspecting request and response headers in Charles Proxy. The issue is a little perplexing, but I'm able to repro it consistently:
In a nutshell, the issue has to do with caching of NSURLRequests using iOS's native NSURLCache with the default policy. It turns out that the request is not cached whenever the response has the header transfer-encoding: chunked. But if the response header is content-length: xxx instead, caching works fine. Specifically, it seems that when the response is chunked, NSURLCache doesn't save the eTag and also neglects appending the if-none-match header to subsequent requests to the same url, and consequently, caching fails (as it should), i.e. a 200 is returned instead of a 304.
I'm testing on the iOS8.2 simulator. Even if you don't have a solution, I'd love to hear if you've experienced the same issue. I've found at least one similar report), and here's a related thread posted by my back-end engineer.
It should work if you manually add the response data to the cache. I've got an image loading class where I want to make sure everything is cached, so I do something like this:
- (void)getImageWithURL:(NSURL *)url onCompletion:(void (^)(UIImage *image, NSError *error))completion {
NSURLRequest *request = [NSURLRequest requestWithURL:url];
UIImage *cachedImage = [self cachedImageForURLRequest:request];
if (cachedImage) {
NSLog(#"Got image from cache.");
completion(cachedImage, nil);
return;
}
[[[NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]] dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
// Manually cache the response.
NSCachedURLResponse *cachedResponse = [[NSCachedURLResponse alloc] initWithResponse:response data:data userInfo:nil storagePolicy:NSURLCacheStorageAllowed];
[[NSURLCache sharedURLCache] storeCachedResponse:cachedResponse forRequest:request];
NSLog(#"Got a fresh image.");
completion([UIImage imageWithData:data], error);
}] resume];
}
- (UIImage *)cachedImageForURLRequest:(NSURLRequest *)urlRequest {
NSCachedURLResponse *cachedResponse = [[NSURLCache sharedURLCache] cachedResponseForRequest:urlRequest];
return [UIImage imageWithData:cachedResponse.data];
}

Prevent initWithContentsOfURL: from using cache

I'm using this line to get the contents of a URL:
NSString *result=[[NSString alloc] initWithContentsOfURL:[NSURL URLWithString:URL]
encoding:NSUTF8StringEncoding
error:nil];
The problem is when there's a bad connection, it loads the contents from cache. Is there a way to avoid this behaviour? For example, clearing the cache or something.
First, it's not recommended to use initWithContentsOfURL:encoding:error to load data from a network resource.
Second, if you want to control caching behavior, you should be using an NSURLRequest. NSURLRequest allows you to customize the caching behavior of the request by setting the cachePolicy of the request. In your case, you want to use NSURLRequestReloadIgnoringLocalCacheData. An example of doing this synchronously using NSURLConnection would be:
NSString *result = nil;
NSData *data = nil;
NSURLResponse *response = nil;
NSURLError *error = nil;
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:URL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:20L];
data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
if (response != nil && [data length] > 0){
result = [NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
}
Note that this is a very naive implementation that does not check the HTTP status code returned, the mime-type of the response, or perform any error handling. It is also not a recommended practice to load network resources synchronously or to do so from the main thread. A better implementation would use sendAsynchronousRequest:completion: or NSURLSession.
However, it does demonstrate at a high level what you would need to do to answer your question: The NSURLRequest specifies that this request should never use the local cache, and the returned data is used to create an instance of NSString.
Simple cache-buster dummy parameter with random value added to URL should work.
And as #Josh-Caswell said, use NSURLRequest. Although in case of proxy servers, just using NSURLRequest may not help and you will still need cache-buster.

Resources