iOS加载本地HTML

来源:互联网 发布:平板如何更新淘宝版本 编辑:程序博客网 时间:2024/06/06 09:27

目标:读取本地的HTML文件来展示H5页面。

  • HTML文件会需要根据URL中不同的Hash Tag来显示不同的页面。例如#!/register显示注册页,#!/login显示登录页等等。
  • HTML文件还需要根据URL传入的参数请求数据。

iOS8以后,苹果推出了新框架WebKit。所以分别用UIWebViewWKWebView来实现看看。
以下仅当HTML文件的文件名为index.html

WebView调试方法是在模拟器显示WebView之后,打开Safari的"开发"Tab的Simulator。

UIWebView

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"];NSString *htmlString = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];NSURL *url = [[NSURL alloc] initWithString:filePath];[self.webView loadHTMLString:htmlString baseURL:url];

以上是把HTML文件读取成字符串再加载到WebView中,这时传递的URL还没有带上Hash Tag和参数。

除了加载HTML字符串以外还可以直接加载文件路径的请求:

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"index" ofType:@"html"];NSURL *url = [[NSURL alloc] initWithString:filePath];NSURLRequest *request = [NSURLRequest requestWithURL:url];[self.webView loadRequest:request];

那么要在URL上加上Hash Tag和传入参数很简单,只需要在URL上拼接上去就可以了。

NSString *component = @"#!/login?id=1&user=admin";NSString *urlString = [filePath stringByAppendingString:component];NSURL *url = [[NSURL alloc] initWithString:urlString];

但是这样有一个问题就是URL传入的时候一些特殊符号会有编码问题。

NSString *encodedComponent = (NSString *)CFBridgingRelease(            CFURLCreateStringByAddingPercentEscapes(            kCFAllocatorDefault,            (CFStringRef)component,            (CFStringRef)@"!$&'()*+,-./:;=?@_~%#",            NULL,            kCFStringEncodingUTF8            )            );NSString *urlString = [filePath stringByAppendingString:component];NSURL *url = [[NSURL alloc] initWithString:urlString];

到此就可以满足上述的目标了。
不过这里有一个其他问题,UIWebView会有内存占用非常高而且不释放导致溢出的问题,这里也顺便记录一下普遍的解决方法。

当收到系统的内存告警时,清除所有缓存的Response。

- (void)didReceiveMemoryWarning{    [super didReceiveMemoryWarning];    [[NSURLCache sharedURLCache] removeAllCachedResponses];}

当加载完一个链接之后,系统会把WebKitCacheModelPreferenceKey这个属性设为1,导致内存不会释放。所以实现UIWebViewDelegate中的- (void)webViewDidFinishLoad:(UIWebView *)webView;方法。在加载完一个链接之后把WebKitCacheModelPreferenceKey属性设为0
并禁用WebKitDiskImageCacheEnabledWebKitOfflineWebApplicationCacheEnabled这两个缓存。

- (void)webViewDidFinishLoad:(UIWebView *)webView{    [[NSUserDefaults standardUserDefaults] setInteger:0 forKey:@"WebKitCacheModelPreferenceKey"];    [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"WebKitDiskImageCacheEnabled"];    [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"WebKitOfflineWebApplicationCacheEnabled"];    [[NSUserDefaults standardUserDefaults] synchronize];}
- (void)dealloc{    [self.webView stopLoading];    [self.webView removeFromSuperview];    self.webView = nil;}

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;
NSURL *fileUrl = [[NSURL alloc] initWithString:filePath];NSURL *url = [NSURL URLWithString:encodedComponent relativeToURL:fileUrl];
  • 还有WebKit框架对跨域进行了安全性检查限制,不允许跨域。所以同样的方法可能在UIWebView能获取到数据,在WKWebView却获取不到数据。

这个问题我暂时未想到较好的解决方法,欢迎指教。或许可以把请求部分提到App中,得到数据之后再通过JavaScript传入HTML中。

  • 看到其他资料说WKWebView使用- (nullable WKNavigation *)loadRequest:(NSURLRequest *)request;来读取本地的HTML无法读取成功,后台会出现如下的提示:Could not create a sandbox extension for /

这个我在用模拟器测试的过程中并没有出现相应的错误。

2 0
原创粉丝点击