I\'m trying to inject data/response from URLRequest into another URLRequest in my cache.
This is just a sample code. It\'s re
I resolved this problem by replacing first guard inside dataTask completionHandler with:
guard error == nil else {
print(error)
if let cr = session.configuration.urlCache?.cachedResponse(for: urlRequest){
let image = UIImage(data: cr.data)
DispatchQueue.main.async {
self?.imageView.image = image
}
}
return
}
If request fails, it will take cached response for that request
This isn't a complete answer, but it should put you in the right direction.
The issue isn't to do with your code, I believe that it's mostly fine. The issue is regarding the response that you get from the landscapeURLString
because the image is stored in Cloudflare. If you use 2 images from the same source, (e.g. try with this bear from wikipedia instead of the image from images.pexels.com) it should work.
I tried printing out the response and headers of downloading the images.pexels.com image and this is what I saw:
response: <NSHTTPURLResponse: 0x600002bf65c0> { URL: https://upload.wikimedia.org/wikipedia/commons/e/e0/Large_Scaled_Forest_Lizard.jpg } { Status Code: 200, Headers {
"Accept-Ranges" = (
bytes
);
"Cache-Control" = (
"public, max-age=31536000"
);
"Content-Length" = (
997361
);
"Content-Type" = (
"image/jpeg"
);
Date = (
"Wed, 31 Oct 2018 11:38:52 GMT"
);
Expires = (
"Thu, 31 Oct 2019 11:38:52 GMT"
);
"Last-Modified" = (
"Fri, 26 Oct 2018 6:31:56 GMT"
);
Server = (
cloudflare
);
Vary = (
"Accept-Encoding"
);
"cf-cache-status" = (
HIT
);
"cf-ray" = (
"4725d67b0ae461bd-BCN"
);
"expect-ct" = (
"max-age=604800, report-uri=\"https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct\""
);
"x-cache" = (
"HIT, MISS"
);
"x-content-type-options" = (
nosniff
);
"x-served-by" = (
"cache-lax8643-LAX, cache-mad9437-MAD"
);
} }
headers: ["Accept-Ranges": "bytes", "Content-Type": "image/jpeg", "Last-Modified": "Fri, 26 Oct 2018 6:31:56 GMT", "Vary": "Accept-Encoding", "cf-ray": "4725d67b0ae461bd-BCN", "Date": "Wed, 31 Oct 2018 11:38:52 GMT", "Server": "cloudflare", "Expires": "Thu, 31 Oct 2019 11:38:52 GMT", "x-content-type-options": "nosniff", "expect-ct": "max-age=604800, report-uri=\"https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct\"", "x-cache": "HIT, MISS", "x-served-by": "cache-lax8643-LAX, cache-mad9437-MAD", "cf-cache-status": "HIT", "Content-Length": "997361", "Cache-Control": "public, max-age=31536000"]
There's probably something in there that is trying to match the request URL with a response field that's causing the cache miss, but I'm not knowledgable enough to know what it is. Somebody else can probably catch it for you (hence why I said that this answer is incomplete).
Welcome to the wonderful world of asynchronous caches. NSURLCache is highly asynchronous. Just because you've shoved data into it doesn't mean it is available for retrieval. You have to let the main run loop return before it will be available, and possibly even wait a little while. The failure to return a response immediately after storing it is not at all unusual. Try dispatching it after five seconds or so.
Second, your cache might be a bit on the small size for storing multi-megabyte images. Try bumping that up and see if it helps.
Finally, what do you mean when you say that you "turn off your Internet?" You say that you're getting a timeout. Normally, if you put the device into Airplane mode with all connectivity disabled, it should not sit there for any significant amount of time before failing with an error indicating no connectivity). If that isn't happening, something strange is happening, almost as if waitsForConnectivity is getting set on the session or something. (You aren't making the network requests in the background, are you? If so, try explicitly setting waitsForConnectivity to NO so that they won't wait for a connection to be available.)
Also, for this usage, you may have to strip out the Vary: Accept-Encoding header or provide a consistent user agent string. That header causes the cache to basically be per-browser. This may cause the cache to behave in unexpected ways, and is probably the cause of the weirdness you're seeing.
Note that stripping out the Vary header is a bit of a hack, and probably isn't the most correct way to fix the issue; ideally, you should tweak whatever outgoing header fields you have to tweak so that it works even with that header present. But you'd have to research it and figure out exactly what fields are needed, because I have no idea. :-)