NSURLSession can handle cache based on the NSURLSessionConfiguration.requestCachePolicy property.
The default value of the requestCachePolicy property is NSURLRequestUseProtocolCachePolicy (0), when the default value is used, the cache validation and loading is transparent to application implementation. For example, when a request is sent to server by NSURLSession, if the cached response is available using etag as validator. Then NSUrlSession will automatically add the "If-None-Match" header in the request before sending the request to server. If server side sees the response data is not changed based on the etag value, the server will return 304 (not modified) to client without response data. When NSURLSession gets the 304 response status from server, it will load the cached response, and call the NSURLSessionDataTask's completion block with the status code and response data loaded from the cached response, so the application will only the status code is 200 instead of 304.
If you want to prevent this automatic cache management, then you can set requestCachePolicy property to NSURLRequestReloadIgnoringLocalCacheData. For example, if etag is used for validate the cache, then nsurlsession will not add the required IF-NONE-MATCH header to the client request, and the server will always return a full response.
Note, if you want to test and verify the cache works properly in your app, you have to log the device http traffic, as the delegate of NSURLSession will never see the 304 status code returned from server, it will be automatically replaced by the status code in the cached response. Besides, do not explicitly add the cache validation header, such as If-None-Match or If-Modified-Since in your request, as NSURLSession will automatically add those header is needed.
For UIWebview, in addition to the default ios cache management NSURLCache, it also has an additional in memory cache management. This in memory cache manager will add the conditional cache header if necessary. So When using NSURLProtocol to intercept the xmlhttprequest, you may see the additional headers are automatially added to the requests. In case server returns 304 to those requests, the UIWebView will automatically load the cached response from memory and return to xmlhttprequest callback method using the status code and data saved in the cached response. When loading cached response from the in memory cache, the default NSURLCached is not involved.