Carica le risorse dal percorso relativo utilizzando l'html locale in uiwebview


121

Ho un'app iOS molto semplice con un'interfaccia utente che carica una pagina di test molto semplice (test.html):

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

Carico questo file test.html nella mia visualizzazione 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];

Funziona bene se faccio riferimento all'immagine senza il percorso relativo e metto l'immagine di riferimento nel percorso principale in Targets -> Copia risorse bundle all'interno di XCode, tuttavia non riesco a farlo funzionare con il percorso relativo come mostrato nel mio file html . Deve esserci un modo per farlo, ho molte immagini, css, file javascript che voglio caricare nella visualizzazione web e vorrei non dover avere tutto nella root e dover cambiare tutti i riferimenti nel mio web app.

Risposte:


286

Ecco come caricare / utilizzare un html locale con relativi riferimenti.

  1. Trascina la risorsa nel tuo progetto xcode (ho trascinato una cartella denominata www dalla mia finestra del Finder), otterrai due opzioni "crea gruppi per ogni cartella aggiunta" e "crea riferimenti a cartelle per ogni cartella aggiunta".
  2. Seleziona l'opzione "crea riferimenti alla cartella ..".
  3. Usa il codice indicato di seguito. Dovrebbe funzionare come un incantesimo.

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

Ora tutti i tuoi collegamenti relativi (come img / .gif, js / .js) nell'html dovrebbero essere risolti.

Swift 3

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

1
Super e Up hanno votato! Qualcuno può spiegare perché "creare riferimenti a cartelle anziché" creare gruppi per eventuali cartelle aggiunte "?
Sean

3
Come sidenote, se si sta cercando di caricare i file JavaScript in contrasto con le immagini, è necessario guardare a questo così: stackoverflow.com/a/3629479/385619
Willster

2
Cosa succede se la directory è profonda n cartelle? Va bene passare una stringa come @"www/app"per la directory arg?
raggio

1
E se carichiamo l'html dai documenti, non dal bundle?
chipbk10

@Sean XCode per impostazione predefinita memorizza tutti i file aggiunti nella cartella principale, i gruppi servono solo a far sembrare bello l'albero del tuo progetto. I riferimenti alle cartelle copiano effettivamente i contenuti così come sono, preservando la struttura della directory. È abbastanza essenziale se vuoi che i tuoi percorsi relativi funzionino sul dispositivo nello stesso modo in cui lo fanno sulla tua macchina da ufficio.
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)
}

Grazie per il codice Swift. Ha funzionato bene insieme alla risposta accettata
Bala Vishnu

Benvenuto! :.) @Bala Vishnu
Weles

Funziona alla grande, ho dovuto scartare la confezione requestURL.
RRikesh

5

Ho stipato tutto in una riga (male lo so) e non ho avuto problemi con esso:

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

1
Nel progetto XCode per la tua immagine sotto il nodo target utilizzi "Relativo al progetto" o "Relativo al gruppo di chiusura"? Stavo usando Relativo al progetto perché nella finestra di dialogo Ottieni informazioni il percorso che mostra quando scelgo Relativo al progetto sembra corretto. Tuttavia sembra caricare correttamente l'immagine quando scelgo relativa al gruppo di chiusura. Ora devo solo fare in modo che la mia pagina intera funzioni correttamente con javascript e css e tutto, grazie!
Matt Palmerlee

Ugh! Questa uiwebview è così fragile, ho iniziato ad aggiungere lentamente test più complessi alla mia pagina di test (cioè impostando l'immagine con css invece che inline nel tag img) e non funzionava, quindi sono tornato a quello che avevo originariamente e non ha funzionato funziona di nuovo! Forse ho a che fare con una sorta di memorizzazione nella cache nella mia uiwebview?
Matt Palmerlee

5

Faccio semplicemente questo:

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

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

Dove "index.html" fa riferimento relativamente a immagini, CSS, javascript, ecc.


2

Risposta rapida 2.

Il riferimento alla classe UIWebView sconsiglia di utilizzare webView.loadRequest (richiesta):

Non utilizzare questo metodo per caricare file HTML locali; utilizza invece loadHTMLString: baseURL :.

In questa soluzione, l'html viene letto in una stringa. L'URL dell'html viene utilizzato per elaborare il percorso e lo trasmette come URL di base.

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

Se questo è il caso, sarebbe bene fare riferimento a dove nel manuale lo consiglia e inserire un estratto da quella pagina - sembra molto senza contesto al momento.
Ben Cox

Il commento di Apple si trova nella pagina del metodo di istanza per loadRequest:
Jeff

0

Sono tornato indietro e ho testato e ritestato questo, sembra che l'unico modo in cui posso farlo funzionare (dato che ho alcuni file nella cartella img e alcuni in js / css, ecc ...) è non farlo usa un percorso relativo alla mia immagine nell'html e fai riferimento a tutto ciò che fa riferimento alla cartella del bundle. Che peccato :(.

<img src="myimage.png" />

0

La risposta di @ sdbrain 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)

-1

In Swift 3.01 utilizzando WKWebView:

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

Ciò si adatta ad alcune delle modifiche alla sintassi più fini nella 3.01 e mantiene la struttura della directory in posizione in modo da poter incorporare i file HTML correlati.


Il prefisso NS non è stato eliminato per i tipi di base chiave dalla 3.x? Questo ha funzionato per me, grazie! let localURL = URL.init(fileURLWithPath: Bundle.main.path(forResource: "index", ofType: "html", inDirectory: "mapa_procesos")!) webView.loadRequest(URLRequest(url: localURL))
Eduardo Gomez
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.