Muat sumber daya dari jalur relatif menggunakan html lokal di uiwebview

121

Saya memiliki aplikasi iOS yang sangat sederhana dengan tampilan uiwebview yang memuat halaman pengujian yang sangat sederhana (test.html):

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

Saya memuat file test.html ini ke tampilan web saya:

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];

Ini berfungsi dengan baik jika saya mereferensikan gambar tanpa jalur relatif dan meletakkan gambar yang direferensikan di jalur root di bawah Target -> Salin Sumber Daya Bundel dalam XCode, namun saya tidak bisa membuatnya bekerja dengan jalur relatif seperti yang ditunjukkan di file html saya . Pasti ada cara untuk melakukan ini, saya punya banyak gambar, css, file javascript yang ingin saya muat ke webview dan saya tidak ingin semuanya ada di root dan harus mengubah semua referensi di web saya aplikasi.

Matt Palmerlee
sumber

Jawaban:

286

Ini adalah cara memuat / menggunakan html lokal dengan referensi relatif.

  1. Seret sumber daya ke dalam proyek xcode Anda (saya menyeret folder bernama www dari jendela pencari saya), Anda akan mendapatkan dua opsi "buat grup untuk folder yang ditambahkan" dan "buat referensi folder untuk folder yang ditambahkan".
  2. Pilih opsi "buat referensi folder ..".
  3. Gunakan kode yang diberikan di bawah ini. Ini harus bekerja seperti pesona.

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

Sekarang semua tautan relatif Anda (seperti img / .gif, js / .js) di html harus diselesaikan.

Cepat 3

    if let path = Bundle.main.path(forResource: "dados", ofType: "html", inDirectory: "root") {
        webView.load( URLRequest(url: URL(fileURLWithPath: path)) )
    }
sdbrain
sumber
1
Super and Up memilih! Adakah yang bisa menjelaskan mengapa "membuat referensi folder sebagai lawan dari" membuat grup untuk folder tambahan "?
Sean
3
Sebagai catatan samping, jika Anda mencoba memuat file javascript dan bukan gambar, Anda harus melihat ini juga: stackoverflow.com/a/3629479/385619
Willster
2
Bagaimana jika direktori itu dalam n folder? Apakah saya tetap bisa meneruskan string seperti @"www/app"untuk direktori arg?
ray
1
Bagaimana jika kita memuat html dari Dokumen, bukan dari Bundle?
chipbk10
@Sean XCode secara default menyimpan semua file yang ditambahkan di folder root, grup hanya untuk membuat pohon proyek Anda terlihat bagus. Referensi folder sebenarnya menyalin konten apa adanya, dengan mempertahankan struktur direktori. Itu sangat penting jika Anda ingin jalur relatif Anda berfungsi pada perangkat dengan cara yang sama seperti yang mereka lakukan di mesin kantor Anda.
Combuster
24

Di 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)
}
Weles
sumber
Terima kasih untuk kode Swiftnya. Bekerja dengan baik bersama dengan Jawaban yang Diterima
Bala Vishnu
Selamat datang! :.) @Bala Vishnu
Weles
Bekerja dengan baik, saya harus membuka bungkusnya requestURL.
RRikesh
5

Saya menjejalkan semuanya menjadi satu baris (buruk saya tahu) dan tidak punya masalah dengan itu:

[webView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"test" 
                                                                                                         ofType:@"html"]
                                                             isDirectory:NO]]];         
PengOne
sumber
1
Dalam project XCode untuk gambar Anda di bawah node target, apakah Anda menggunakan "Relative to project" atau "Relative to Enclosing Group"? Saya menggunakan Relatif ke proyek karena dalam dialog dapatkan info, jalur yang ditampilkan saat saya memilih Relatif ke proyek terlihat benar. Namun tampaknya memuat gambar dengan benar ketika saya memilih relatif terhadap grup penutup. Sekarang saya baru saja pergi agar halaman lengkap saya berfungsi dengan benar dengan javascript dan css dan semuanya, terima kasih!
Matt Palmerlee
Ugh! Tampilan web ini sangat rapuh, saya mulai perlahan menambahkan tes yang lebih kompleks ke halaman pengujian saya (yaitu mengatur gambar dengan css alih-alih sebaris di tag img) dan itu tidak berfungsi jadi saya kembali ke apa yang saya semula dan ternyata tidak tidak bekerja lagi! Mungkin saya berurusan dengan semacam cache di uiwebview saya?
Matt Palmerlee
5

Saya hanya melakukan ini:

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

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

Di mana "index.html" secara relatif merujuk pada gambar, CSS, javascript, dll.

McStopher tua
sumber
2

Jawaban cepat 2.

The UIWebView Kelas Referensi menyarankan untuk tidak menggunakan webView.loadRequest (permintaan):

Jangan gunakan metode ini untuk memuat file HTML lokal; sebagai gantinya, gunakan loadHTMLString: baseURL :.

Dalam solusi ini, html dibaca menjadi string. Url html digunakan untuk menentukan jalur, dan meneruskannya sebagai url dasar.

let url = bundle.URLForResource("index", withExtension: "html", subdirectory: "htmlFileFolder")
let html = try String(contentsOfURL: url)
let base = url.URLByDeletingLastPathComponent
webView.loadHTMLString(html, baseURL: base)
Ini bukan saya
sumber
Jika ini masalahnya, alangkah baiknya untuk merujuk ke bagian mana dalam manual yang menyarankan hal ini dan menyisipkan kutipan dari halaman itu - tampaknya sangat banyak tanpa konteks saat ini.
Ben Cox
Komentar Apple ada di halaman Metode Instans untuk loadRequest:
Jeff
0

Saya telah kembali dan menguji dan menguji ulang ini, tampaknya satu-satunya cara saya bisa membuatnya berfungsi (karena saya memiliki beberapa file di folder img dan beberapa di js / css, dll ...) adalah tidak gunakan jalur relatif ke gambar saya di html dan semuanya direferensikan ke folder bundel. Sayang sekali :(.

<img src="myimage.png" />
Matt Palmerlee
sumber
0

Jawaban @ sdbrain di Swift 3:

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

Di Swift 3.01 menggunakan WKWebView:

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

Ini menyesuaikan beberapa perubahan sintaks yang lebih baik di 3.01 dan menjaga struktur direktori tetap di tempatnya sehingga Anda dapat menyematkan file HTML terkait.

Bently Bobo
sumber
Bukankah prefiks NS dikeluarkan untuk jenis pondasi kunci sejak 3.x? Itu berhasil untuk saya, terima kasih! let localURL = URL.init(fileURLWithPath: Bundle.main.path(forResource: "index", ofType: "html", inDirectory: "mapa_procesos")!) webView.loadRequest(URLRequest(url: localURL))
Eduardo Gomez