AFNetworking 3.0 on disk image caching - ios

Is it possible in AFNetworking to cache image on disk for more than session? For example for a week or month. In my project i used SDWebImage and AFNetworking, but few days ago i found that AFNetworking has the same functionality as SDWebImage, so a removed SDWebImage and wrote such code to store image on disk:
for ImageView
NSURLRequest *imageRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:url]
cachePolicy:NSURLRequestReturnCacheDataElseLoad
timeoutInterval:60];
[imageView setImageWithURLRequest:imageRequest placeholderImage:placeholderImage success:nil failure:nil];
Download image to use in future
NSURLRequest *imageRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:url]
cachePolicy:NSURLRequestReturnCacheDataElseLoad
timeoutInterval:60];
[[AFImageDownloader defaultInstance] downloadImageForURLRequest:imageRequest success:nil failure:nil];
Get downloaded image
NSURLRequest *imageRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:url]
cachePolicy:NSURLRequestReturnCacheDataElseLoad
timeoutInterval:60];
UIImage *image = [[AFImageDownloader defaultInstance].imageCache imageforRequest:imageRequest withAdditionalIdentifier:nil];
But all this working only per session, after i loaded all images i turn off internet and restart my app, result - no images in cache.
Also i try to add such code in AppDelegate:
NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:2 * 1024 * 1024
diskCapacity:100 * 1024 * 1024
diskPath:nil];
[NSURLCache setSharedURLCache:sharedCache];
But i still can't cache images for longer than session.
(Sorry for my english)

Images are cached on disk using standard NSURLCache built in iOS, meaning that if your responses include proper cache headers, those items should end up on disk in the cache. So for example headers should look like:
"Accept-Ranges" = bytes;
"Cache-Control" = "max-age=604800";
Connection = close;
"Content-Length" = 3808;
"Content-Type" = "image/png";
Date = "Tue, 29 Mar 2016 19:55:52 GMT";
Etag = "\"5630989d-ee0\"";
Expires = "Tue, 05 Apr 2016 19:55:52 GMT";
"Last-Modified" = "Wed, 28 Oct 2015 09:42:53 GMT";
Server = nginx;
also if you have downloaded an image and want to get it from the disk cache do:
NSURLRequest *imageRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:url]
cachePolicy:NSURLRequestReturnCacheDataElseLoad
timeoutInterval:60];
UIImage *image = [UIImage imageWithData:[[AFImageDownloader defaultURLCache] cachedResponseForRequest:imageRequest].data];

Related

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.

Image Caching With AFNetworking

The cache mechanism of AFNetworking is not working for me, I have an image of 500ko with big dimension and I want to cache it. But every time I close the application and open it again I have to wait for 20sec for the image to load so the cache system is not working here is the code:
I tried :
[imageView setImageWithURL:[NSURL URLWithString:imageURL]
placeholderImage:[UIImage imageNamed:#"placeholder"]];
and then tried :
NSURLRequest *imageRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:imageURL]
cachePolicy:NSURLRequestReturnCacheDataElseLoad
timeoutInterval:60];
[imageView setImageWithURLRequest:imageRequest
placeholderImage:[UIImage imageNamed:#"placeholder"]
success:nil
failure:nil];
NSURLCache does not write to disk in its default so we need to declare a shared NSURLCache in app delegate :
NSURLCache *sharedCache = [[NSURLCache alloc] initWithMemoryCapacity:2 * 1024 * 1024
diskCapacity:100 * 1024 * 1024
diskPath:nil];
[NSURLCache setSharedURLCache:sharedCache];
Reference

How to load cached requests with AFNetworking 2.0 if app is reopen?

I have been using AFNetworking 2.0. Cache works well if the app is in foreground, or came from background. But when I kill the app and reopen it, cache is cleared. Is there a way to make it persistent? Thanks
You can cache from disk using the NSURLRequestReturnCacheDataElseLoad cache policy:
Objective-c
NSURLRequest *imageRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:imageURL]
cachePolicy:NSURLRequestReturnCacheDataElseLoad
timeoutInterval:60];
[imageView setImageWithURLRequest:imageRequest
placeholderImage:[UIImage imageNamed:#"placeholder"]
success:nil
failure:nil];
Swift
let imageRequest = NSURLRequest(URL: NSURL.URLWithString(imageUrl),
cachePolicy: NSURLRequestCachePolicy.ReturnCacheDataElseLoad,
timeoutInterval: 60)
imageView.setImageWithURLRequest(imageRequest,
placeholderImage: UIImage(named: "placeholder"),
success: nil,
failure: nil)
Source: here

Strange NSURLConnection caching behaviour

I have a simple method that takes a url and loads it from the server:
- (void)loadURL:(NSString*)url
{
NSMutableURLRequest* request = [[NSMutableURLRequest alloc] init];
request.HTTPMethod = #"GET";
request.URL = [NSURL URLWithString:url];
NSHTTPURLResponse* response;
[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
}
The server returns a response with max-age of 1 day.
Problem is that when I run these 3 lines repeatedly, 2 of them randomly miss the cache and reload the response:
[self loadURL:#"http://192.168.0.105:8080/users/51bdbc73808897302f000001/avatar?size=200x200&access_token=abcdefghijklmnopqrstuvwxyzzp77eDLqub3EWfXGe4c09RoyipmXgcENwfE6EV9yzvgp5VTSZww"];
[self loadURL:#"http://192.168.0.105:8080/users/51ee9d4e263d08fe04000003/avatar?size=200x200&access_token=abcdefghijklmnopqrstuvwxyzzp77eDLqub3EWfXGe4c09RoyipmXgcENwfE6EV9yzvgp5VTSZww"];
[self loadURL:#"http://192.168.0.105:8080/users/51d17b81de38c60b20000006/avatar?size=200x200&access_token=abcdefghijklmnopqrstuvwxyzzp77eDLqub3EWfXGe4c09RoyipmXgcENwfE6EV9yzvgp5VTSZww"];
If I add some random unique data (&x, &y, &z) to each request's query string it fixes the problem:
[self loadURL:#"http://192.168.0.105:8080/users/51bdbc73808897302f000001/avatar?size=200x200&access_token=abcdefghijklmnopqrstuvwxyzzp77eDLqub3EWfXGe4c09RoyipmXgcENwfE6EV9yzvgp5VTSZww&x"];
[self loadURL:#"http://192.168.0.105:8080/users/51ee9d4e263d08fe04000003/avatar?size=200x200&access_token=abcdefghijklmnopqrstuvwxyzzp77eDLqub3EWfXGe4c09RoyipmXgcENwfE6EV9yzvgp5VTSZww&y"];
[self loadURL:#"http://192.168.0.105:8080/users/51d17b81de38c60b20000006/avatar?size=200x200&access_token=abcdefghijklmnopqrstuvwxyzzp77eDLqub3EWfXGe4c09RoyipmXgcENwfE6EV9yzvgp5VTSZww&z"];
Also, if I reduce the length of query strings to 80 chars it fixes the problem as well:
[self loadURL:#"http://192.168.0.105:8080/users/51bdbc73808897302f000001/avatar?size=200x200&access_token=abcdefghijklmnopqrstuvwxyzzp77eDLqub3EWfXGe4c09Royipm"];
[self loadURL:#"http://192.168.0.105:8080/users/51ee9d4e263d08fe04000003/avatar?size=200x200&access_token=abcdefghijklmnopqrstuvwxyzzp77eDLqub3EWfXGe4c09Royipm"];
[self loadURL:#"http://192.168.0.105:8080/users/51d17b81de38c60b20000006/avatar?size=200x200&access_token=abcdefghijklmnopqrstuvwxyzzp77eDLqub3EWfXGe4c09Royipm"];
What's going on?
Is this a bug in iOS? How can I fix it?
P.S: I've tested this in an empty application with no extra stuff both on iOS 5 and 6.
Set the caching behaviour in the NSURLRequest with requestWithURL:cachePolicy:timeoutInterval:. Try:
- (void)loadURL:(NSString*)url
{
NSURL *url = [NSURL URLWithString:url];
NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy: NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:10.0];
NSHTTPURLResponse* response;
[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:nil];
}
Possibly also use NSURLRequestReloadIgnoringLocalAndRemoteCacheData for cachePolicy.
you might want to use ASIHTTPRequest instead
http://allseeing-i.com/ASIHTTPRequest/

NSURLCache not used by NSURLConnection / AFNetworkingOperation

When I start a request with the NSURLRequestReturnCacheDataElseLoad policy I expect to get the result from the NSURLCache if any, no matter how old it is. However, the system always tries to reach the server the request points to and returns an error if the server doesn't answer.
I use the UIImageView category of AFNetworking for the request.
NSURLRequest* request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:60.0];
__weak __typeof(self) weakSelf = self;
NSLog(#"[%#] %#", request.URL, [[NSURLCache sharedURLCache] cachedResponseForRequest:request]); // this returns an instance of NSCachedURLResponse!
[self setImageWithURLRequest:request placeholderImage:nil success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
__typeof(weakSelf) self = weakSelf;
self.image = image;
} failure:NULL];
This will not set the image even if asking the NSURLCache directly will return a valid NSCachedURLResponse.
The app is running on iOS6 only, so there should be no problems with on-disk cache as far as I know?!
Any help is appreciated! Thanks!
This is a know issue. Please refer this discussion on AFNetworking github page for a workaround.

Resources