Tải tài nguyên từ đường dẫn tương đối bằng cách sử dụng html cục bộ trong uiwebview


121

Tôi có một ứng dụng iOS rất đơn giản với uiwebview đang tải một trang thử nghiệm rất đơn giản (test.html):

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

Tôi tải tệp test.html này vào chế độ xem web của mình:

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

Điều này hoạt động tốt nếu tôi tham chiếu hình ảnh mà không có đường dẫn tương đối và đặt hình ảnh được tham chiếu trong đường dẫn gốc trong Mục tiêu -> Sao chép tài nguyên gói trong XCode, tuy nhiên tôi không thể làm cho nó hoạt động với đường dẫn tương đối như được hiển thị trong tệp html của tôi . Phải có một cách để làm điều này, tôi có rất nhiều hình ảnh, tệp css, javascript mà tôi muốn tải vào webview và tôi không muốn phải có mọi thứ trong gốc và phải thay đổi tất cả các tham chiếu trong web của mình ứng dụng.

Câu trả lời:


286

Đây là cách tải / sử dụng html cục bộ với các tham chiếu tương đối.

  1. Kéo tài nguyên vào dự án xcode của bạn (tôi đã kéo một thư mục có tên www từ cửa sổ công cụ tìm của tôi), bạn sẽ nhận được hai tùy chọn "tạo nhóm cho bất kỳ thư mục được thêm nào" và "tạo tham chiếu thư mục cho bất kỳ thư mục được thêm nào".
  2. Chọn tùy chọn "tạo tham chiếu thư mục ..".
  3. Sử dụng mã dưới đây. Nó sẽ hoạt động như một sự quyến rũ.

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

Bây giờ tất cả các liên kết tương đối của bạn (như img / .gif, js / .js) trong html sẽ được giải quyết.

Swift 3

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

1
Super trở lên bình chọn! Có ai có thể giải thích lý do tại sao "tạo tham chiếu thư mục chống lại" tạo nhóm cho bất kỳ thư mục nào được thêm vào "không?
Sean

3
Là một sidenote, nếu bạn đang cố gắng để tải file javascript như trái ngược với hình ảnh, bạn sẽ cần phải xem xét điều này cũng như: stackoverflow.com/a/3629479/385619
Willster

2
Điều gì sẽ xảy ra nếu thư mục có n thư mục sâu? Có thể truyền một chuỗi như @"www/app"cho thư mục arg không?
ray

1
Điều gì sẽ xảy ra nếu chúng tôi tải html từ Tài liệu, không phải từ Gói?
chipbk10

@Sean XCode theo mặc định lưu trữ tất cả các tệp được thêm vào thư mục gốc, các nhóm chỉ để làm cho cây dự án của bạn trông đẹp mắt. Tham chiếu thư mục thực sự sao chép nội dung nguyên trạng, giữ nguyên cấu trúc thư mục. Điều đó khá cần thiết nếu bạn muốn các đường dẫn tương đối của mình hoạt động trên thiết bị giống như cách chúng làm trên máy văn phòng của bạn.
Combuster

24

Trong 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)
}

Cảm ơn vì mã Swift. Làm việc tốt cùng với sự trả lời được chấp nhận
Bala Vishnu

Chào mừng! :.) @Bala Vishnu
Chào mừng

Hoạt động tuyệt vời, tôi đã phải mở requestURLmặc dù.
RRikesh

5

Tôi đã nhồi nhét mọi thứ vào một dòng (tôi biết là tệ) và không gặp khó khăn gì với nó:

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

1
Trong dự án XCode cho hình ảnh của bạn dưới nút mục tiêu, bạn sử dụng "Liên quan đến dự án" hay "Liên quan đến Nhóm bao gồm"? Tôi đang sử dụng Tương đối để dự án vì trong hộp thoại nhận thông tin, đường dẫn mà nó hiển thị khi tôi chọn Tương đối để dự án trông chính xác. Tuy nhiên, nó xuất hiện để tải hình ảnh chính xác khi tôi chọn liên quan đến nhóm bao quanh. Bây giờ tôi chỉ cần truy cập để trang đầy đủ của tôi hoạt động chính xác với javascript và css và tất cả, cảm ơn!
Matt Palmerlee

Ặc! Uiwebview này rất mỏng manh, tôi bắt đầu từ từ thêm các bài kiểm tra phức tạp hơn vào trang kiểm tra của mình (tức là đặt hình ảnh bằng css thay vì nội tuyến trong thẻ img) và nó không hoạt động nên tôi đã hoàn nguyên về những gì tôi đã có ban đầu và nó không hoạt động. không hoạt động nữa! Có lẽ tôi đang xử lý một số loại bộ nhớ đệm trong uiwebview của mình?
Matt Palmerlee

5

Tôi chỉ đơn giản làm điều này:

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

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

Trong đó "index.html" tương đối tham chiếu đến hình ảnh, CSS, javascript, v.v.


2

Câu trả lời nhanh 2.

Các UIWebView Lớp tham khảo lời khuyên không nên sử dụng webView.loadRequest (theo yêu cầu):

Không sử dụng phương pháp này để tải các tệp HTML cục bộ; thay vào đó, hãy sử dụng loadHTMLString: baseURL:.

Trong giải pháp này, html được đọc thành một chuỗi. Url của html được sử dụng để tìm ra đường dẫn và chuyển nó làm url cơ sở.

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

Nếu đúng như vậy, sẽ rất tốt nếu bạn tham khảo nơi trong sách hướng dẫn sử dụng thông báo này và chèn một đoạn trích từ trang đó - có vẻ như hiện tại rất nhiều điều không có ngữ cảnh.
Ben Cox

Nhận xét của Apple trên trang Phương pháp phiên bản cho loadRequest:
Jeff

0

Tôi đã quay lại và kiểm tra và kiểm tra lại điều này, có vẻ như cách duy nhất tôi có thể làm cho nó hoạt động (vì tôi có một số tệp trong thư mục img và một số tệp trong js / css, v.v.) là không sử dụng một đường dẫn tương đối đến hình ảnh của tôi trong html và có mọi thứ được tham chiếu đến thư mục gói. Xấu hổ làm sao :(.

<img src="myimage.png" />

0

Câu trả lời của @ sdbrain trong Swift 3:

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

-1

Trong Swift 3.01 sử dụng WKWebView:

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

Điều này điều chỉnh một số thay đổi cú pháp tốt hơn trong 3.01 và giữ nguyên cấu trúc thư mục để bạn có thể nhúng các tệp HTML liên quan.


Có phải tiền tố NS đã bị loại bỏ cho các loại nền tảng chính kể từ 3.x không? Điều đó đã làm các thủ thuật cho tôi, cảm ơn! let localURL = URL.init(fileURLWithPath: Bundle.main.path(forResource: "index", ofType: "html", inDirectory: "mapa_procesos")!) webView.loadRequest(URLRequest(url: localURL))
Eduardo Gomez
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.