iOS URL Loading System

iOS URL Loading System包含如下:

iOS URL Loading System_第1张图片

官方文档参考

本文主要介绍三个部分:NSURLProtocol、Cookie Storage、Cache Management。

NSURLProtocol

NSURLProtocol参考链接
参考代码(增加对WKWebView的支持)

NSURLCache 和 NSCachedURLResponse

说完NSURLProtocol,就到了缓存阶段。
缓存管理类为对URL请求的回应提供了缓存。NSURLCache类为URL提供了通用缓存(这里注意,WKWebView从iOS9之后就有了WKWebsiteDataStore类来管理WKWebView http请求的缓存以及Cookie等)

  1. 调用[NSURLCache sharedURLCache]方法,默认会创建缓存区([NSURLCache sharedURLCache].currentDiskUsage = 86016Byte,[NSURLCache sharedURLCache].currentMemoryUsage = 0,iOS5之后默认是磁盘缓存),其中缓存区Memory capacity: 4 megabytes ,Disk capacity: 20 megabytes
  2. 当然我们也可以通过自定义的方式来实现是否缓存,感谢此链接。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
    CusURLCache *cache = [[CusURLCache alloc] initWithMemoryCapacity:(2*1024*1024) diskCapacity:((100 * 1024 * 1024)) diskPath:nil];
    [CusURLCache setSharedURLCache:cache];
    return YES;
}

//  CusURLCache.h
//  Http测试
//
//  Created by XinWeizhou on 2017/4/28.
//  Copyright © 2017年 XinWeizhou. All rights reserved.
//

#import 

@interface CusURLCache : NSURLCache

@end

#import "CusURLCache.h"

@implementation CusURLCache
// CusURLCache告诉系统我有怎样的已缓存的NSCachedURLResponse对象(或者没有),这里拦截了http://img1.gtimg.com/news/pics/hv1/138/183/2205/143426928.jpeg,并且做了假的NSURLResponse以供缓存
- (NSCachedURLResponse *)cachedResponseForRequest:(NSURLRequest *)request {
    
    NSURL *url = [request URL];
    NSLog(@"request.string = %@",request.URL.absoluteString);
    if ([url.absoluteString isEqualToString:@"http://img1.gtimg.com/news/pics/hv1/138/183/2205/143426928.jpeg"]) {
        
        NSLog(@"request = %@",request);
        
        NSURLResponse *response =
        [[NSURLResponse alloc] initWithURL:url
                                  MIMEType:@"text/plain"
                     expectedContentLength:1
                          textEncodingName:nil];
        NSCachedURLResponse *cachedResponse =
        [[NSCachedURLResponse alloc] initWithResponse:response
                                                 data:[NSData dataWithBytes:" " length:1]];
         // 有人可能会认为只需要返回假的响应对象就够了,没必要缓存它。但这样会因响应对象被系统释放而导致app crash。不知道为何为会这样,可能是iOS的bug(Mac OS X 10.5.x也存在同样问题,而10.4.x及更早的系统上没有问题),也可能是URL Loading System内部类之间的依赖所致。                                        
        [super storeCachedResponse:cachedResponse forRequest:request];
    }
    
    return [super cachedResponseForRequest:request];
   
}

- (void)storeCachedResponse:(NSCachedURLResponse *)cachedResponse forRequest:(NSURLRequest *)request {
    NSLog(@"request2 = %@ === response2 = %@",request,cachedResponse);
    [super storeCachedResponse:cachedResponse forRequest:request];
}

说明:NSURLCache 将对每一个NSURLRequest对象遵守缓存策略(NSURLRequestCachePolicy),策略如下所示:
1. NSURLRequestUseProtocolCachePolicy 默认的缓存策略,对特定的URL请求使用网络协议中实现的缓存逻辑
2. NSURLRequestReloadIgnoringLocalCacheData 忽略本地缓存,重新请请求
3. NSURLRequestReloadIgnoringLocalAndRemoteCacheData 忽略本地和远程缓存,重新请求(未实现)
4. NSURLRequestReturnCacheDataElseLoad 有缓存则从中加载,如果没有则去请求
5. NSURLRequestReturnCacheDataDontLoad 无网络状态下不去请求,一直加载本地缓存数据无论其是否存在
6. NSURLRequestReloadRevalidatingCacheData 默从原始地址确认缓存数据的合法性之后,缓存数据才可使用,否则请求原始地址(未实现)

注意:NSURLCache缓存不缓存request及response,不是由request得缓存策略决定的,缓存策略只是说明是否加载已经存在的缓存,缓存机制有URL Loading System提供。

Cookie Storage

现在谈谈httpCookie相关:NSHTTPCookie和NSHTTPCookieStorage。(这里注意,WKWebView从iOS9之后就有了WKWebsiteDataStore类来管理WKWebView http请求的缓存以及Cookie等)

  1. cookie和NSURLRequest的关系,除非NSURLRequest明确指定不使用cookie(HTTPShouldHandleCookies设为NO),否则URL loading
    system会自动为NSURLRequest发送合适的存储cookie。

  2. NSHTTPCookieStorage:从NSURLResponse返回的cookie也会根据NSHTTPCookieStorage的cookie访问策略(cookie acceptance policy)接收到系统中。

    通过NSHTTPCookieStorage可读取/修改cookie接收策略,默认为NSHTTPCookieAcceptPolicyAlways.

    -(NSHTTPCookieAcceptPolicy)cookieAcceptPolicy;

    -(void)setCookieAcceptPolicy:(NSHTTPCookieAcceptPolicy)aPolicy.

    一共有三种cookie accept policy。typedef enum {
    NSHTTPCookieAcceptPolicyAlways,
    NSHTTPCookieAcceptPolicyNever,
    NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain
    } NSHTTPCookieAcceptPolicy;

    NSHTTPCookieAcceptPolicyAlways:接收所有cookie,默认策略.

  3. NSHTTPCookieStorage通知

    当NSHTTPCookieStorage实例中的cookies变化时发出此通知
    NSHTTPCookieManagerCookiesChangedNotification

    当NSHTTPCookieStorage实例的cookie acceptance policy变化时发出此通知
    NSHTTPCookieManagerAcceptPolicyChangedNotification

  4. NSHTTPCookie

    使用NSHTTPCookie的类方法可以将NSHTTPCookie实例与HTTP headerField相互转换:

// 从响应头获取Cookie信息:
 + (NSArray *)cookiesWithResponseHeaderFields:(NSDictionary *)headerFields forURL:(NSURL *)theURL;
// 手动cookie创建例子:
   NSMutableDictionary *cookieProperties = [NSMutableDictionary dictionary];  // 创建cookie属性字典
   [cookieProperties setObject:@"username" forKey:NSHTTPCookieName]; // 手动设置cookie的属性
   [cookieProperties setObject:@"Boat" forKey:NSHTTPCookieValue];
   [cookieProperties setObject:@"yzwind.com" forKey:NSHTTPCookieDomain];
   [cookieProperties setObject:@"www.yzwind.com" forKey:NSHTTPCookieOriginURL];
   [cookieProperties setObject:@"/" forKey:NSHTTPCookiePath];
   [cookieProperties setObject:@"0" forKey:NSHTTPCookieVersion];
   NSHTTPCookie *cookie = [NSHTTPCookie cookieWithProperties:cookieProperties];  
 // 用Cookie设置请求头:
NSDictionary * headers = [NSHTTPCookie requestHeaderFieldsWithCookies:@[cookie]];
// 请求头这里只设置了Cookie
request.allHTTPHeaderFields = headers;
打印结果
headers = {
   Cookie = "username = Boat";
}
// 直接给请求头设置Cookie:
[request setValue:"username = Boat" forHTTPHeaderField:@"Cookie"];  

NSHTTPCookie Class Reference

你可能感兴趣的:(iOS URL Loading System)