IOS Network -- NSURLCache sets the network request cache and iosnsurlcache
Today, I checked the HTTP protocol and saw the cache-control in the response Header. So I went into some in-depth research. I found a class I ignored in iOS-NSURLCache class.
NSURLCache
NSURLCache is used to cache network requests, that is, NSURLRequest. Then, the corresponding cache is performed according to the NSURLCache policy we set.
First, we will introduce various policies.
Policy |
Meaning |
UseProtocolCachePolicy |
Default behavior |
ReloadIgnoringLocalCacheData |
No Cache |
ReloadIgnoringLocalAndRemoteCacheData * |
I am serious and do not use any Cache |
ReturnCacheDataElseLoad |
Use the cache (whether it expires or not). If the cache does not exist, load it from the network. |
ReturnCacheDataDontLoad |
Offline mode: Use cache (whether it expires or not),NoAttach from Network |
ReloadRevalidatingCacheData * |
Verify before use |
ReloadIgnoringLocalAndRemoteCacheData and ReloadRevalidatingCacheData are not implemented.
When creating a request to use cache, We will select the above policy, that is
+ (instancetype)requestWithURL:(NSURL *)URL cachePolicy:(NSURLRequestCachePolicy)cachePolicy timeoutInterval:(NSTimeInterval)timeoutInterval;
This method allows us to set the policy and time, and then the request will be scheduled according to the policy and time.
Feel NSURLCache
Here, the default Cache Policy ReturnCacheDataElseLoad is used,
Create an NSURLCache class
NSURLCache *URLCache = [[NSURLCache alloc] initWithMemoryCapacity:4 * 1024 * 1024 diskCapacity:0 diskPath:nil];[NSURLCache setSharedURLCache:URLCache];
1. here we can see that we have set 4*1024*1024 memory (4 MB) for the Creation parameters, without using disk space.
2. NSURLCache uses [NSURLCache sharedURLCache] to create a default cache action. The default value is 4 (MB) memory and 20 (MB) disk space. Here we use a custom one, so we need to setSharedCache.
Then create a request and connection for the request.
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://172.16.25.44/test1.php"] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:3];connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];[connection start];
Implement the NSURLConnectionDelegate Protocol
-(void)connectionDidFinishLoading:(NSURLConnection *)connection{ NSLog(@"finish");}
Run the request. The tool used here is Charles.
You can see that there is only one request, and then you can view the console output
2015-08-04 09:29:55.297 requestCache[19405:6375355] finish2015-08-04 09:29:55.301 requestCache[19405:6375355] finish2015-08-04 09:29:55.310 requestCache[19405:6375355] finish2015-08-04 09:29:55.451 requestCache[19405:6375355] finish2015-08-04 09:29:55.618 requestCache[19405:6375355] finish2015-08-04 09:29:55.784 requestCache[19405:6375355] finish2015-08-04 09:29:55.984 requestCache[19405:6375355] finish2015-08-04 09:29:56.120 requestCache[19405:6375355] finish
Therefore, multiple requests only carry out one request, because NSURLCache caches a response for us in the memory. Once the same request exists, the cache will be used.
Cache persistence
If the local disk is set, the cache will be automatically persisted for us and NSURLCache creation code will be modified.
NSURLCache *URLCache = [[NSURLCache alloc] initWithMemoryCapacity:4 * 1024 * 1024 diskCapacity:20 * 1024 * 1024 diskPath:nil]; [NSURLCache setSharedURLCache:URLCache];
Set a local disk of 20 mb, run the program, and check whether the request remains unchanged. However, when the program runs a request, it will find that a remote request will not proceed!
Open the sandbox and find that there are three files under Library/Caches/bundleId + project name/
Isn't that sqlite! Originally, NSURLCache helped us store requests to the database using sqlite, and then the cache will be called when there are the same requests!
You can think of webView. If you load a static page, you don't have to use only one request, and how nice the remote request will be when the effect is to be updated!
Default policy
The default policy is UseProtocolCachePolicy. Literally, the Protocol cache policy is used. But what is the protocol Cache Policy?
In the HTTP response Header, a field is cache-control, which is used by the server to tell the client how to use the cache.
The following is a response header.
We can see that the specified cache-control behavior is public, max-age = 5
Here we will first introduce various commands
According to the table above, we can see that the response header requires that all content be cached. The cache will expire in 5 seconds, and the request will be sent to the remote server in 5 seconds.
The corresponding PHP header ("Cache-Control: public, max-age = 5 ");
Counterfeit response
If we want some requests to have specific responses, we can make our own response.
NSLog(@"%@",[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject]); NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://172.16.25.44/test1.php"] cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:3]; NSURLCache * cache = [NSURLCache sharedURLCache]; NSData *contentData = [@"123" dataUsingEncoding:NSUTF8StringEncoding]; NSURLResponse *response = [[NSURLResponse alloc] initWithURL:[NSURL URLWithString:@"http://172.16.25.44/test1.php"] MIMEType:@"text/html" expectedContentLength:1000 textEncodingName:@"UTF-8"]; NSCachedURLResponse *cacheRespone = [[NSCachedURLResponse alloc] initWithResponse:response data:contentData]; [cache storeCachedResponse:cacheRespone forRequest:request]; connection = [[NSURLConnection alloc] initWithRequest:request delegate:self]; [connection start];
The above Code creates a response to the @ "http: // 172.16.25.44/test1.php" request and stores the response in the cache.
Implementation
-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{ NSString *dataString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"%@",dataString);}
The output result is as follows:
2015-08-04 09:48:58.825 requestCache[19503:6441561] 1232015-08-04 09:48:58.826 requestCache[19503:6441561] finish2015-08-04 09:48:58.983 requestCache[19503:6441561] 1232015-08-04 09:48:58.984 requestCache[19503:6441561] finish2015-08-04 09:48:59.167 requestCache[19503:6441561] 1232015-08-04 09:48:59.167 requestCache[19503:6441561] finish2015-08-04 09:48:59.334 requestCache[19503:6441561] 1232015-08-04 09:48:59.335 requestCache[19503:6441561] finish
We can see that the output is our custom 123, rather than the 1 returned by the server.
Modify response content
To modify the response content, we need to implement the NSURLConnectionDataDelegate Protocol and implement
-(NSCachedURLResponse *) connection :( NSURLConnection *) connection willCacheResponse :( NSCachedURLResponse *) cachedResponse {NSMutableData * mutableData = [[cachedResponse data] mutableCopy]; // Add NSCachedURLResponse * response = [[NSCachedURLResponse alloc] initWithResponse: cachedResponse. response data: mutableData]; return response ;}
The NSCachedURLResponse attribute should be readonly, so we need to create a variable copy to increase or decrease the content if we want to add the content.