はじめに
UIWebViewにおいて、ローカルに置いてあるhtmlや、文字列から直接WebViewに読み込んだ場合
主に下記のメソッドを使用するケースが多いと思います。
-loadHTMLString:baseURL:
-loadData:MIMEType:textEncodingName:baseURL:
//HTML文字列
NSString *htmlString = @"<html>...";
//HTMLを読み込み
[self.webView loadHTMLString:htmlString baseURL:nil];
しかし、上記のメソッドを使用した場合UIWebView(javascript)のgoBack,goForwardのhistroyStackに反映されず、
[self.webView goBack];
や[self.webView goForward];
で遷移させる事ができなくなってしまいます。
自前でWebViewのスタックを管理して表示履歴を操作する事はできなくは無いですが結構しんどかったので、
手っ取り早く修正する方法を紹介したいと思います。
解決策
いろいろと調べていると、loadRequest:
を使用してページを読み込めばスタックに反映される事が分かったので、
どうにかしてNSURLRequest形式でhtmlデータを取得すれば良さそうです。
html文字列からリクエストする場合
ファイル化されておらず、変数保持している文字列などを読み込みたい場合は、
一旦キャッシュディレクトリに保存してファイルに直接アクセスします。
(別途ファイルの削除などの制御はあったほうがいいかもしれません)
//html文字列
NSString *htmlString = @"<html>...";
//WebViewの遷移履歴を保持するためにリソースファイル化してアクセスする
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *documentDir = [paths objectAtIndex:0];
if (documentDir) {
documentDir = [documentDir stringByAppendingPathComponent:@"example.html"];
//Cacheディレクトリにexample.htmlという名前でファイルを生成
[htmlString writeToFile:documentDir atomically:YES encoding:NSUTF8StringEncoding error:nil];
//filePathを指定してNSURL形式で取得 & リクエスト
[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:documentDir]]];
}
バンドルからリクエストする場合
アプリバンドル内にすでにリソースファイルとして登録されている場合は、
保存処理がいらないのでもっと簡単です。
//filePath
NSString *path = [[NSBundle mainBundle] pathForResource:@"example" ofType:@"html"];
if (path){
//filePathを指定してNSURL形式で取得 & リクエスト
[self.webView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:path]]];
}
終わりに
やっつけですが、UIWebViewにローカルファイルを読み込む場合のスタック周りの問題回避方法をご紹介しました。
文字列から直接リクエストする場合は毎回ファイルへの書き込み処理が発生してしまうのがどうなのかなぁという印象です。
(もっといい解決策は無いのかしら。。。)
Webviewがっつりなアプリとかだともっとちゃんと実装を考えた方がいいかもしれません。
取り急ぎ対応tipsとして認識していただけると幸いです。