项目里有个需求:因为推出的页游资源文件较大,需要把资源文件放在本地

网上已经有几种实现方案了:

调用UIWebView(void)loadHTMLString:(NSString *)string baseURL:(nullable NSURL *)baseURL;

http://blog.csdn.net/zachman1993/article/details/52693826

使用NSURLCache

http://www.jianshu.com/p/7f3be7c30c77

这里主要介绍下我用NSURLProtocol的实现版本

NSURLProcol是 URL Loading System的重要组成部分,它可以拦截、转发App所发出的网络请求,具体介绍可以看这篇文章

实现步骤很简单,只需要创建一个NSURLProtocol的子类,并重写startLoading这个方法,为需要转发的NSURLRequest生成一个NSURLResponse就可以了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
- (void)startLoading
{

[NSURLProtocol setProperty:@YES forKey:URLProtocolHandledKey inRequest:(NSMutableURLRequest *)[self request]];

NSMutableURLRequest *mutableReqeust = [[self request] mutableCopy];
mutableReqeust = [self redirectHostInRequset:mutableReqeust]; //处理url

if ([mutableReqeust.URL.scheme isEqualToString:@"file"]) {// 需要转发的URL是file://开头的
NSData *data = [NSData dataWithContentsOfURL:mutableReqeust.URL];//本地数据

NSString *path = mutableReqeust.URL.absoluteString;
path = [path stringByReplacingOccurrencesOfString:@"file://" withString:@""];
NSString *mimeType = [self getMIMETypeWithCAPIAtFilePath:path]; //mimeType
//生成response
NSURLResponse *response = [[NSURLResponse alloc] initWithURL:[self request].URL
MIMEType:mimeType
expectedContentLength:data.length
textEncodingName:nil];
//转发
[self.client URLProtocol:self
didReceiveResponse:response
cacheStoragePolicy:NSURLCacheStorageNotAllowed];

[self.client URLProtocol:self didLoadData:data];
[self.client URLProtocolDidFinishLoading:self];

}else{ //不需要转发的URL走默认方法
self.connection = [NSURLConnection connectionWithRequest:[self request] delegate:self];
}

}

+(NSMutableURLRequest*)redirectHostInRequset:(NSMutableURLRequest*)request

这个函数是用来重定向URL的,里面放的是业务逻辑,如果改request需要处理,则把url修改成本地对应文件的request;如果不需要处理,则直接返回原URL