Carregar recursos do caminho relativo usando o html local no uiwebview

121

Eu tenho um aplicativo iOS muito simples, com um uiwebview carregando uma página de teste muito simples (test.html):

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

Carrego esse arquivo test.html na minha visualização da 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];

Isso funciona bem se eu referenciar a imagem sem o caminho relativo e colocar a imagem referenciada no caminho raiz em Destinos -> Copiar recursos do pacote no XCode, no entanto, não consigo fazê-lo funcionar com o caminho relativo, conforme mostrado no meu arquivo html . Deve haver uma maneira de fazer isso, tenho muitas imagens, css, arquivos javascript que quero carregar na visualização da web e gostaria de não ter que ter tudo na raiz e alterar todas as referências na minha web aplicativo.

Matt Palmerlee
fonte

Respostas:

286

Isto é como carregar / usar um html local com referências relativas.

  1. Arraste o recurso para o seu projeto xcode (arrastei uma pasta chamada www da minha janela do localizador), você terá duas opções "criar grupos para todas as pastas adicionadas" e "criar referências de pastas para todas as pastas adicionadas".
  2. Selecione a opção "criar referências de pasta ..".
  3. Use o código abaixo fornecido. Deve funcionar como um encanto.

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

Agora todos os seus links relativos (como img / .gif, js / .js) no html devem ser resolvidos.

Swift 3

    if let path = Bundle.main.path(forResource: "dados", ofType: "html", inDirectory: "root") {
        webView.load( URLRequest(url: URL(fileURLWithPath: path)) )
    }
sdbrain
fonte
1
Super e Up votado! Alguém pode explicar por que "criar pasta referências como se opor a 'criar grupos para todas as pastas adicionadas'?
Sean
3
Como nota de rodapé, se você estiver tentando carregar arquivos javascript em vez de imagens, também precisará ver isso: stackoverflow.com/a/3629479/385619
Willster 13/14
2
E se o diretório tiver n pastas? É bom passar uma string como @"www/app"para o diretório arg?
ray
1
E se carregarmos o html dos Documentos, não do Bundle?
chipbk10
Por padrão, o @Sean XCode armazena todos os arquivos adicionados na pasta raiz; os grupos são apenas para tornar sua árvore de projeto com boa aparência. As referências de pasta realmente copiam o conteúdo como estão, preservando a estrutura de diretórios. Isso é essencial se você deseja que seus caminhos relativos funcionem no dispositivo da mesma forma que na máquina do escritório.
Combuster
24

Em 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
fonte
Obrigado pelo código Swift. Funcionou bem, juntamente com a resposta aceita
Bala Vishnu
Bem-vinda! .:) @Bala Vishnu
Weles
Funciona muito bem, eu tive que desembrulhar o requestURLembora.
precisa saber é o seguinte
5

Coloquei tudo em uma linha (pelo menos eu sei) e não tive problemas com isso:

[webView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"test" 
                                                                                                         ofType:@"html"]
                                                             isDirectory:NO]]];         
PengOne
fonte
1
No projeto XCode para sua imagem no nó de destinos, você usa "Relativo ao projeto" ou "Relativo ao grupo encerrado"? Eu estava usando o Relative para projetar porque, na caixa de diálogo obter informações, o caminho que aparece quando escolho Relativo ao projeto parece correto. No entanto, parece carregar a imagem corretamente quando eu escolho em relação ao grupo anexo. Agora eu apenas vou conseguir que minha página inteira funcione corretamente com javascript e css e tudo, obrigado!
Matt Palmerlee
Ugh! Este uiwebview é tão frágil, comecei lentamente a adicionar testes mais complexos à minha página de teste (ou seja, definindo a imagem com css em vez de embutido na tag img) e como não estava funcionando, voltei ao que tinha originalmente e não funcionou. trabalhe de novo! Talvez eu esteja lidando com algum tipo de cache no meu uiwebview?
Matt Palmerlee
5

Eu simplesmente faço isso:

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

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

Onde "index.html" referencia relativamente imagens, CSS, javascript etc.

Old McStopher
fonte
2

Resposta rápida 2.

A referência de classe UIWebView desaconselha o uso de webView.loadRequest (request):

Não use esse método para carregar arquivos HTML locais; em vez disso, use loadHTMLString: baseURL :.

Nesta solução, o html é lido em uma string. O URL do html é usado para descobrir o caminho e o passa como um URL 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)
Este não sou eu
fonte
Se for esse o caso, seria bom consultar onde o manual aconselha isso e inserir um trecho dessa página - parece muito sem contexto no momento.
Ben Cox
O comentário da Apple está na página Método da instância para loadRequest:
Jeff
0

Voltei, testei e re-testei isso, parece que a única maneira de fazê-lo funcionar (já que tenho alguns arquivos na pasta img e outros em js / css, etc ...) não é use um caminho relativo para minha imagem no html e tenha tudo relacionado à pasta do pacote. Que pena :(.

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

A resposta de @ sdbrain no 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
fonte
-1

No Swift 3.01 usando o WKWebView:

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

Isso ajusta algumas das alterações mais refinadas da sintaxe no 3.01 e mantém a estrutura de diretórios no lugar para que você possa incorporar arquivos HTML relacionados.

Bently Bobo
fonte
O prefixo NS não foi descartado para os principais tipos de fundação desde a versão 3.x? Isso fez o truque para mim, obrigado! let localURL = URL.init(fileURLWithPath: Bundle.main.path(forResource: "index", ofType: "html", inDirectory: "mapa_procesos")!) webView.loadRequest(URLRequest(url: localURL))
Eduardo Gomez