uiwebviewのローカルhtmlを使用して相対パスからリソースを読み込みます


121

私は非常にシンプルなiOSアプリで、uiwebviewが非常にシンプルなテストページ(test.html)をロードしています。

<html>
<body>
<img src="img/myimage.png" />
</body>
</html>

このtest.htmlファイルをWebビューにロードします。

NSURL *url = [[NSBundle mainBundle] URLForResource:@"test" withExtension:@"html"];
NSString *html = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
NSURL *baseUrl = [NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]];
[webView loadHTMLString:html baseURL:baseUrl];

相対パスなしで画像を参照し、参照された画像を[ターゲット]-> [XCode内のバンドルリソースのコピー]の下のルートパスに配置すると、これは正常に機能しますが、htmlファイルに示されているように相対パスで機能しません。これを行う方法があるはずです。Webviewにロードしたい画像、CSS、JavaScriptファイルがたくさんあります。ルートにすべてを入れて、Webのすべての参照を変更する必要はありません。アプリ。

回答:


286

これは、相対参照でローカルhtmlをロード/使用する方法です。

  1. リソースをxcodeプロジェクトにドラッグします(ファインダーウィンドウからwwwという名前のフォルダーをドラッグしました)、「追加のフォルダーのグループを作成する」と「追加のフォルダーのフォルダー参照を作成する」という2つのオプションがあります。
  2. 「フォルダー参照の作成...」オプションを選択します。
  3. 以下のコードを使用してください。それは魅力のように機能するはずです。

    NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"index" ofType:@"html" inDirectory:@"www"]];
    [webview loadRequest:[NSURLRequest requestWithURL:url]];

これで、html内のすべての相対リンク(img / .gif、js / .jsなど)が解決されます。

スウィフト3

    if let path = Bundle.main.path(forResource: "dados", ofType: "html", inDirectory: "root") {
        webView.load( URLRequest(url: URL(fileURLWithPath: path)) )
    }

1
スーパーとアップに投票しました!「追加されたフォルダのグループを作成する」のではなく「フォルダ参照を作成する」理由を誰かが説明できますか?
Sean

3
追記として、あなたがイメージとは対照的に、JavaScriptファイルをロードしようとしている場合、あなたにもこれを見てする必要がありますstackoverflow.com/a/3629479/385619
Willster

2
ディレクトリがn個のフォルダの深さの場合はどうなりますか?@"www/app"ディレクトリargのような文字列を渡しても大丈夫ですか?
光線

1
バンドルからではなく、ドキュメントからHTMLをロードするとどうなりますか?
chipbk10 2015

@Sean XCodeはデフォルトで、ルートフォルダーに追加されたすべてのファイルを保存します。グループは、プロジェクトツリーを美しく見せるためだけのものです。フォルダ参照は実際にコンテンツをそのままコピーし、ディレクトリ構造を維持します。相対パスをオフィスマシンで行うのと同じ方法でデバイスで機能させる場合、これは非常に重要です。
Combuster 2015

24

Swiftの場合:

 func pathForResource(  name: String?, 
                        ofType ext: String?, 
                        inDirectory subpath: String?) -> String?  {

  // **name:** Name of Hmtl
  // **ofType ext:** extension for type of file. In this case "html"
  // **inDirectory subpath:** the folder where are the file. 
  //    In this case the file is in root folder

    let path = NSBundle.mainBundle().pathForResource(             "dados",
                                                     ofType:      "html", 
                                                     inDirectory: "root")
    var requestURL = NSURL(string:path!)
    var request = NSURLRequest(URL:requestURL)

    webView.loadRequest(request)
}

Swiftコードをありがとう。承認された回答とうまく機能した
Bala Vishnu

ようこそ!:。)@Bala Vishnu
ウェールズ2014年

素晴らしい作品ですが、私はアンラップする必要requestURLがありました。
RRikesh

5

私はすべてを1行に詰め込みました(私が知っている悪いことです)、それで問題はありませんでした:

[webView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"test" 
                                                                                                         ofType:@"html"]
                                                             isDirectory:NO]]];         

1
ターゲットノードの下の画像のXCodeプロジェクトで、「プロジェクトに対して相対」または「囲んでいるグループに対して相対」を使用しますか?相対的なプロジェクトを使用していたのは、[情報を取得]ダイアログで、[相対的なプロジェクト]を選択したときに表示されるパスが正しいためです。しかし、囲んでいるグループに対して相対的に選択すると、画像が正しく読み込まれるように見えます。これで、ページ全体をJavaScriptとCSSで正しく機能させることができました。ありがとうございます。
Matt Palmerlee、2011年

うわっ!このuiwebviewは非常に壊れやすいので、テストページにさらに複雑なテストをゆっくりと追加し始め(つまり、imgタグでインラインではなくcssを使用して画像を設定)、機能しなかったため、元の状態に戻しましたもう働かない!多分私は私のuiwebviewで何らかのキャッシュを扱っていますか?
Matt Palmerlee、2011年

5

私は単にこれを行います:

    UIWebView *webView = [[[UIWebView alloc] init] autorelease];

    NSURL *url = [[NSBundle mainBundle] URLForResource:@"index" withExtension:@"html"];
    NSURLRequest* request = [NSURLRequest requestWithURL:url];
    [webView loadRequest:request];

「index.html」が画像、CSS、JavaScriptなどを相対的に参照している場合


2

迅速な回答2。

UIWebViewクラスリファレンスは webView.loadRequest(リクエスト)を使用しないように助言します:

このメソッドを使用してローカルHTMLファイルをロードしないでください。代わりに、loadHTMLString:baseURL:を使用してください。

このソリューションでは、htmlが文字列に読み込まれます。HTMLのURLはパスを計算するために使用され、それをベースURLとして渡します。

let url = bundle.URLForResource("index", withExtension: "html", subdirectory: "htmlFileFolder")
let html = try String(contentsOfURL: url)
let base = url.URLByDeletingLastPathComponent
webView.loadHTMLString(html, baseURL: base)

これが事実である場合、それがマニュアルのどこにそれを助言し、そのページからの抜粋を挿入するのが良いでしょう-現時点ではほとんど文脈がないようです。
ベンコックス

AppleのコメントはloadRequestのインスタンスメソッドのページにある:
ジェフ

0

私は戻ってこれをテストして再テストしました、それを機能させる唯一の方法は(imgフォルダーにいくつかのファイルがあり、js / cssなどにいくつかあるので) HTML内の画像への相対パスを使用し、すべてがバンドルフォルダーを参照するようにします。残念だ :(。

<img src="myimage.png" />

0

Swift 3での@sdbrainの回答:

    let url = URL.init(fileURLWithPath: Bundle.main.path(forResource: "index", ofType: "html", inDirectory: "www")!)
    webView.loadRequest(NSURLRequest.init(url: url) as URLRequest)

-1

WKWebViewを使用するSwift 3.01の場合:

let localURL = URL.init(fileURLWithPath: Bundle.main.path(forResource: "index", ofType: "html", inDirectory: "CWP")!)
myWebView.load(NSURLRequest.init(url: localURL) as URLRequest)

これにより、3.01でのより細かい構文変更の一部が調整され、関連するHTMLファイルを埋め込めるようにディレクトリ構造が維持されます。


3.x以降、主要なファンデーションタイプのNSプレフィックスは削除されていませんか?これでうまくいきました。ありがとうございます。 let localURL = URL.init(fileURLWithPath: Bundle.main.path(forResource: "index", ofType: "html", inDirectory: "mapa_procesos")!) webView.loadRequest(URLRequest(url: localURL))
Eduardo Gomez
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.