Laden Sie Ressourcen aus dem relativen Pfad mit lokalem HTML in uiwebview

121

Ich habe eine sehr einfache iOS-App mit einer uiwebview, die eine sehr einfache Testseite (test.html) lädt:

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

Ich lade diese test.html-Datei in meine Webansicht:

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

Dies funktioniert einwandfrei, wenn ich auf das Bild ohne den relativen Pfad verweise und das referenzierte Bild in den Stammpfad unter Ziele -> Bundle-Ressourcen in XCode kopiere. Es kann jedoch nicht mit dem relativen Pfad funktionieren, wie in meiner HTML-Datei gezeigt . Es muss eine Möglichkeit geben, dies zu tun. Ich habe viele Bilder, CSS und Javascript-Dateien, die ich in die Webansicht laden möchte, und ich möchte nicht alles im Stammverzeichnis haben und alle Referenzen in meinem Web ändern müssen App.

Matt Palmerlee
quelle

Antworten:

286

So laden / verwenden Sie ein lokales HTML mit relativen Referenzen.

  1. Ziehen Sie die Ressource in Ihr xcode-Projekt (ich habe einen Ordner mit dem Namen www aus meinem Finder-Fenster gezogen). Sie erhalten zwei Optionen: "Gruppen für hinzugefügte Ordner erstellen" und "Ordnerreferenzen für hinzugefügte Ordner erstellen".
  2. Wählen Sie die Option "Ordnerreferenzen erstellen ..".
  3. Verwenden Sie den unten angegebenen Code. Es sollte wie ein Zauber wirken.

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

Jetzt sollten alle Ihre relativen Links (wie img / .gif, js / .js) im HTML aufgelöst werden.

Swift 3

    if let path = Bundle.main.path(forResource: "dados", ofType: "html", inDirectory: "root") {
        webView.load( URLRequest(url: URL(fileURLWithPath: path)) )
    }
sdbrain
quelle
1
Super und Up gewählt! Kann jemand erklären, warum "Ordnerreferenzen erstellen im Gegensatz zu" Gruppen für hinzugefügte Ordner erstellen "?
Sean
3
Als Nebenbemerkung, wenn Sie versuchen, Javascript-Dateien im Gegensatz zu Bildern zu laden, müssen Sie auch dies betrachten: stackoverflow.com/a/3629479/385619
Willster
2
Was ist, wenn das Verzeichnis n Ordner tief ist? Ist es in Ordnung, eine Zeichenfolge wie @"www/app"für das Verzeichnis arg zu übergeben?
Ray
1
Was ist, wenn wir den HTML-Code aus den Dokumenten laden, nicht aus dem Bundle?
Chipbk10
@Sean XCode speichert standardmäßig alle im Stammordner hinzugefügten Dateien. Gruppen dienen nur dazu, dass Ihr Projektbaum gut aussieht. Ordnerreferenzen kopieren den Inhalt tatsächlich wie er ist, wobei die Verzeichnisstruktur erhalten bleibt. Dies ist sehr wichtig, wenn Sie möchten, dass Ihre relativen Pfade auf dem Gerät genauso funktionieren wie auf Ihrem Büromaschinen.
Combuster
24

In 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
quelle
Danke für den Swift-Code. Arbeitete gut zusammen mit der akzeptierten Antwort
Bala Vishnu
Herzlich willkommen! :.) @Bala Vishnu
Weles
Funktioniert super, ich musste das requestURLallerdings auspacken .
RRikesh
5

Ich habe alles in einer Zeile zusammengefasst (schlecht, ich weiß) und hatte keine Probleme damit:

[webView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"test" 
                                                                                                         ofType:@"html"]
                                                             isDirectory:NO]]];         
PengOne
quelle
1
Verwenden Sie im XCode-Projekt für Ihr Bild unter dem Zielknoten "Relativ zum Projekt" oder "Relativ zur Einschlussgruppe"? Ich habe Relative to project verwendet, da im Dialogfeld get info der Pfad angezeigt wird, der angezeigt wird, wenn ich Relative to project auswähle. Es scheint jedoch, dass das Bild korrekt geladen wird, wenn ich relativ zur umschließenden Gruppe wähle. Jetzt gehe ich einfach dazu, dass meine ganze Seite mit Javascript und CSS richtig funktioniert und alles, danke!
Matt Palmerlee
Pfui! Diese uiwebview ist so zerbrechlich, dass ich langsam begann, meiner Testseite komplexere Tests hinzuzufügen (dh das Bild mit CSS anstelle von Inline im img-Tag zu setzen), und es funktionierte nicht, also kehrte ich zu dem zurück, was ich ursprünglich hatte, und es tat es nicht funktioniert nicht wieder! Vielleicht habe ich es mit einer Art Caching in meinem UI-Web zu tun?
Matt Palmerlee
5

Ich mache einfach das:

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

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

Wobei "index.html" relativ auf Bilder, CSS, Javascript usw. verweist.

Alter McStopher
quelle
2

Schnelle Antwort 2.

Die UIWebView-Klassenreferenz rät von der Verwendung von webView.loadRequest (Anfrage) ab:

Verwenden Sie diese Methode nicht, um lokale HTML-Dateien zu laden. Verwenden Sie stattdessen loadHTMLString: baseURL:.

In dieser Lösung wird der HTML-Code in eine Zeichenfolge eingelesen. Die HTML-URL wird verwendet, um den Pfad zu ermitteln, und übergibt diese als Basis-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)
Das bin nicht ich
quelle
Wenn dies der Fall ist, sollten Sie sich darauf beziehen, wo im Handbuch dies empfohlen wird, und einen Auszug aus dieser Seite einfügen - es scheint im Moment sehr ohne Kontext zu sein.
Ben Cox
Apples Kommentar befindet sich auf der Seite Instanzmethode für loadRequest:
Jeff
0

Ich bin zurückgegangen und habe dies getestet und erneut getestet. Es scheint, dass der einzige Weg, wie ich es zum Laufen bringen kann (da ich einige Dateien im img-Ordner und einige in js / css usw. habe), nicht darin besteht, dies zu tun Verwenden Sie einen relativen Pfad zu meinem Bild im HTML-Code und lassen Sie alles auf den Bundle-Ordner verweisen. Schade :(.

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

@ sdbrains Antwort in 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
quelle
-1

In Swift 3.01 mit WKWebView:

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

Dadurch werden einige der feineren Syntaxänderungen in 3.01 berücksichtigt und die Verzeichnisstruktur beibehalten, sodass Sie verwandte HTML-Dateien einbetten können.

Bently Bobo
quelle
Wurde das NS-Präfix für die wichtigsten Foundation-Typen seit 3.x nicht mehr gelöscht? Das hat den Trick für mich getan, danke! let localURL = URL.init(fileURLWithPath: Bundle.main.path(forResource: "index", ofType: "html", inDirectory: "mapa_procesos")!) webView.loadRequest(URLRequest(url: localURL))
Eduardo Gomez