简介
- 读取本地的HTML文件来展示H5页面。
HTML文件会需要根据URL中不同的
Hash Tag来显示不同的页面。例如#!/register显示注册页,#!/login显示登录页等等。
HTML文件还需要根据URL传入的参数请求数据。
iOS8以后,苹果推出了新框架WebKit。所以分别用UIWebView和WKWebView来实现看看。
以下仅当HTML文件的文件名为index.html。
WebView调试方法是在模拟器显示WebView之后,打开Safari的"开发"Tab的Simulator。
UIWebView
1 | NSString *filePath = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"]; |
以上是把HTML文件读取成字符串再加载到WebView中,这时传递的URL还没有带上Hash Tag和参数。
除了加载HTML字符串以外还可以直接加载文件路径的请求:
1 | NSString *filePath = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"]; |
那么要在URL上加上Hash Tag和传入参数很简单,只需要在URL上拼接上去就可以了。
1 | NSString *component = @"#!/login?id=1&user=admin"; |
但是这样有一个问题就是URL传入的时候一些特殊符号会有编码问题。
1 | NSString *encodedComponent = (NSString *)CFBridgingRelease( |
到此就可以满足上述的目标了。
不过这里有一个其他问题,UIWebView会有内存占用非常高而且不释放导致溢出的问题,这里也顺便记录一下普遍的解决方法。
当收到系统的内存告警时,清除所有缓存的Response。
1 | - (void)didReceiveMemoryWarning |
当加载完一个链接之后,系统会把WebKitCacheModelPreferenceKey这个属性设为1,导致内存不会释放。所以实现UIWebViewDelegate中的- (void)webViewDidFinishLoad:(UIWebView *)webView;方法。在加载完一个链接之后把WebKitCacheModelPreferenceKey属性设为0,并禁用WebKitDiskImageCacheEnabled,WebKitOfflineWebApplicationCacheEnabled这两个缓存。
1 | - (void)webViewDidFinishLoad:(UIWebView *)webView |
1 | - (void)dealloc |
WKWebView
WKWebView速度更快,内存占用少。使用的方法和UIWebView的方法差不多。
列几个关于WKWebView的问题:
- 使用
WKWebView的时候不能用上面的那种方式去拼接URL。
需要用:- (nullable instancetype)initWithString:(NSString *)URLString relativeToURL:(nullable NSURL *)baseURL NS_DESIGNATED_INITIALIZER;+ (nullable instancetype)URLWithString:(NSString *)URLString relativeToURL:(nullable NSURL *)baseURL;
1 | NSURL *fileUrl = [[NSURL alloc] initWithString:filePath]; |
- 还有WebKit框架对跨域进行了安全性检查限制,不允许跨域。所以同样的方法可能在
UIWebView能获取到数据,在WKWebView却获取不到数据。
这个问题我暂时未想到较好的解决方法,欢迎指教。或许可以把请求部分提到App中,得到数据之后再通过JavaScript传入HTML中。
- 看到其他资料说
WKWebView使用- (nullable WKNavigation *)loadRequest:(NSURLRequest *)request;来读取本地的HTML无法读取成功,后台会出现如下的提示:Could not create a sandbox extension for /
这个我在用模拟器测试的过程中并没有出现相应的错误。