Załaduj zasoby ze ścieżki względnej za pomocą lokalnego kodu HTML w uiwebview

121

Mam bardzo prostą aplikację na iOS z uiwebview ładującą bardzo prostą stronę testową (test.html):

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

Ładuję ten plik test.html do mojego widoku internetowego:

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

Działa to dobrze, jeśli odwołuję się do obrazu bez ścieżki względnej i umieszczę obraz, do którego się odwołujemy, w ścieżce głównej w obszarze Cele -> Kopiuj zasoby pakietu w XCode, jednak nie mogę go uruchomić ze ścieżką względną, jak pokazano w moim pliku html . Musi istnieć sposób, aby to zrobić, mam wiele obrazów, plików css, javascript, które chcę załadować do webview i nie chciałbym mieć wszystkiego w katalogu głównym i zmieniać wszystkie odniesienia w mojej sieci aplikacja.

Matt Palmerlee
źródło

Odpowiedzi:

286

Oto jak załadować / używać lokalnego HTML ze względnymi odniesieniami.

  1. Przeciągnij zasób do projektu xcode (przeciągnąłem folder o nazwie www z okna wyszukiwarki), otrzymasz dwie opcje „utwórz grupy dla wszystkich dodanych folderów” i „utwórz odniesienia do folderów dla dowolnych dodanych folderów”.
  2. Wybierz opcję „utwórz odniesienia do folderów ..”.
  3. Użyj poniższego kodu. Powinien działać jak urok.

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

Teraz wszystkie linki względne (takie jak img / .gif, js / .js) w html powinny zostać rozwiązane.

Szybki 3

    if let path = Bundle.main.path(forResource: "dados", ofType: "html", inDirectory: "root") {
        webView.load( URLRequest(url: URL(fileURLWithPath: path)) )
    }
sdbrain
źródło
1
Głosowali Super and Up! Czy ktoś może wyjaśnić, dlaczego „twórz odwołania do folderów, a nie„ twórz grupy dla dowolnych dodanych folderów ”?
Sean
3
Na marginesie, jeśli próbujesz załadować pliki javascript, a nie obrazy, musisz również przyjrzeć się temu: stackoverflow.com/a/3629479/385619
Willster
2
Co jeśli katalog jest głęboki na n folderów? Czy można przekazać ciąg znaków, taki jak @"www/app"dla katalogu arg?
ray
1
Co jeśli załadujemy html z Dokumentów, a nie z Paczki?
chipbk10
@Sean XCode domyślnie przechowuje wszystkie pliki dodane w folderze głównym, grupy służą tylko do nadania drzewu projektu dobrego wyglądu. Odnośniki do folderów w rzeczywistości kopiują zawartość bez zmian, zachowując strukturę katalogów. Jest to bardzo istotne, jeśli chcesz, aby Twoje względne ścieżki działały na urządzeniu w taki sam sposób, jak na komputerze biurowym.
Combuster
24

W 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
źródło
Dzięki za kod Swift. Działało dobrze wraz z zaakceptowaną odpowiedzią
Bala Vishnu,
Witamy! :.) @Bala Vishnu
Weles
Działa świetnie, musiałem jednak odpakować requestURL.
RRikesh
5

Wepchnąłem wszystko w jedną linię (źle wiem) i nie miałem z tym żadnych problemów:

[webView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"test" 
                                                                                                         ofType:@"html"]
                                                             isDirectory:NO]]];         
PengOne
źródło
1
Czy w projekcie XCode obrazu w węźle docelowym używasz opcji „Względem projektu” lub „Względem grupy obejmującej”? Używałem Względnego do projektu, ponieważ w oknie dialogowym pobierania informacji ścieżka, którą pokazuje po wybraniu opcji Względny do projektu, wygląda poprawnie. Wygląda jednak na to, że obraz ładuje się poprawnie, gdy wybieram względem otaczającej grupy. Teraz po prostu chcę, aby moja cała strona działała poprawnie z javascript i css i wszystko, dzięki!
Matt Palmerlee
Fuj! Ten uiwebview jest tak delikatny, że zacząłem powoli dodawać bardziej złożone testy do mojej strony testowej (tj. Ustawianie obrazu za pomocą css zamiast inline w tagu img) i nie działało, więc wróciłem do tego, co miałem pierwotnie i nie zadziałało znowu nie działa! Może mam do czynienia z jakimś buforowaniem w moim uiwebview?
Matt Palmerlee
5

Po prostu robię to:

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

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

Gdzie „index.html” zawiera odniesienia do obrazów, CSS, javascript itp.

Stary McStopher
źródło
2

Szybka odpowiedź 2.

Dokumentacja klasy UIWebView odradza używanie webView.loadRequest (żądanie):

Nie używaj tej metody do ładowania lokalnych plików HTML; zamiast tego użyj loadHTMLString: baseURL :.

W tym rozwiązaniu html jest wczytywany do ciągu. Adres URL html jest używany do określenia ścieżki i przekazuje ją jako podstawowy adres 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)
To nie ja
źródło
Jeśli tak jest, dobrze byłoby odnieść się do miejsca w instrukcji, w którym to zaleca i wstawić fragment tej strony - w tej chwili wydaje się to bardzo bez kontekstu.
Ben Cox
Komentarz Apple znajduje się na stronie Instance Method dla loadRequest:
Jeff,
0

Wróciłem, przetestowałem i ponownie przetestowałem to, wydaje się, że jedynym sposobem, w jaki mogę to uruchomić (ponieważ mam kilka plików w folderze img, a niektóre w js / css, itp ...) nie jest użyj względnej ścieżki do mojego obrazu w html i miej wszystko, co odnosi się do folderu pakietu. Jaka szkoda :(.

<img src="myimage.png" />
Matt Palmerlee
źródło
0

Odpowiedź @ sdbrain w 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
źródło
-1

W Swift 3.01 przy użyciu WKWebView:

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

Dostosowuje się to do niektórych drobniejszych zmian składni w wersji 3.01 i utrzymuje strukturę katalogów na miejscu, dzięki czemu można osadzać powiązane pliki HTML.

Bently Bobo
źródło
Czy przedrostek NS nie został usunięty dla kluczowych typów fundamentów od 3.x? To mi wystarczyło, dzięki! let localURL = URL.init(fileURLWithPath: Bundle.main.path(forResource: "index", ofType: "html", inDirectory: "mapa_procesos")!) webView.loadRequest(URLRequest(url: localURL))
Eduardo Gomez