Загружать ресурсы по относительному пути с помощью локального HTML в uiwebview

121

У меня очень простое приложение для iOS с uiwebview, загружающим очень простую тестовую страницу (test.html):

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

Я загружаю этот файл test.html в свое веб-представление:

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

Это отлично работает, если я ссылаюсь на изображение без относительного пути и помещаю указанное изображение в корневой путь в разделе Targets -> Copy Bundle Resources в XCode, однако я не могу заставить его работать с относительным путем, как показано в моем html файле , Должен быть способ сделать это, у меня есть много файлов изображений, css, javascript, которые я хочу загрузить в веб-просмотр, и я бы не хотел, чтобы все было в корне и мне пришлось менять все ссылки в моем веб-сайте. приложение.

Мэтт Палмерли
источник

Ответы:

286

Вот как загрузить / использовать локальный html с относительными ссылками.

  1. Перетащите ресурс в свой проект xcode (я перетащил папку с именем www из своего окна поиска), вы получите два варианта «создать группы для любых добавленных папок» и «создать ссылки на папки для любых добавленных папок».
  2. Выберите параметр «создать ссылки на папки ..».
  3. Используйте приведенный ниже код. Это должно работать как шарм.

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

Теперь все ваши относительные ссылки (например, img / .gif, js / .js) в html должны быть разрешены.

Swift 3

    if let path = Bundle.main.path(forResource: "dados", ofType: "html", inDirectory: "root") {
        webView.load( URLRequest(url: URL(fileURLWithPath: path)) )
    }
sdbrain
источник
1
Проголосовали Super и Up! Может ли кто-нибудь объяснить, почему «создавать ссылки на папки, а не« создавать группы для любых добавленных папок »?»
Шон,
3
В качестве примечания, если вы пытаетесь загрузить файлы javascript, а не изображения, вам также нужно взглянуть на это: stackoverflow.com/a/3629479/385619
Willster
2
Что, если в глубине каталога находится n папок? Можно ли передавать строку, например, @"www/app"для каталога arg?
Ray
1
Что если мы загрузим html из документов, а не из пакета?
chipbk10
@Sean XCode по умолчанию сохраняет все файлы, добавленные в корневую папку, группы предназначены только для того, чтобы дерево вашего проекта выглядело хорошо. Ссылки на папки фактически копируют содержимое как есть, сохраняя структуру каталогов. Это очень важно, если вы хотите, чтобы ваши относительные пути работали на устройстве так же, как на вашем офисном компьютере.
Combuster
24

В 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
источник
Спасибо за код Swift. Хорошо работал вместе с Принятым ответом
Бала Вишну
Добро пожаловать! :.) @Bala Vishnu
Weles
Отлично работает, requestURLхотя пришлось развернуть .
Рикеш 01
5

Запихал все в одну строчку (плохо знаю) и никаких проблем с этим не было:

[webView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"test" 
                                                                                                         ofType:@"html"]
                                                             isDirectory:NO]]];         
PengOne
источник
1
В проекте XCode для вашего изображения в узле целей вы используете «Относительно проекта» или «Относительно окружающей группы»? Я использовал Относительный для проекта, потому что в диалоговом окне получения информации путь, который он показывает, когда я выбираю Относительный для проекта, выглядит правильным. Однако кажется, что изображение загружается правильно, когда я выбираю относительно включающей группы. Теперь я просто хочу, чтобы моя полная страница корректно работала с javascript и css и всем остальным, спасибо!
Мэтт Палмерли
Тьфу! Этот uiwebview настолько хрупок, что я начал медленно добавлять более сложные тесты на свою тестовую страницу (то есть устанавливать изображение с помощью css вместо встроенного в тег img), и он не работал, поэтому я вернулся к тому, что у меня был изначально, и он не опять не работает! Может у меня в uiwebview какое то кеширование?
Мэтт Палмерли
5

Я просто делаю это:

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

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

Где index.html относительно ссылается на изображения, CSS, javascript и т. Д.

Старый Макстофер
источник
2

Быстрый ответ 2.

Класс UIWebView Справочный советует против использования webView.loadRequest (запроса):

Не используйте этот метод для загрузки локальных файлов HTML; вместо этого используйте loadHTMLString: baseURL :.

В этом решении html читается в строку. URL-адрес html используется для определения пути и передает его как базовый 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)
Это не я
источник
Если это так, было бы хорошо сослаться на то, где в руководстве говорится об этом, и вставить отрывок с этой страницы - на данный момент это кажется очень без контекста.
Бен Кокс,
Комментарий Apple находится на странице метода экземпляра для loadRequest:
Джефф,
0

Я вернулся и протестировал и повторно протестировал это, похоже, что единственный способ заставить его работать (поскольку у меня есть некоторые файлы в папке img, а некоторые в js / css и т.д.) - это не использовать относительный путь к моему изображению в html и иметь все ссылки на папку пакета. Какая досада :(.

<img src="myimage.png" />
Мэтт Палмерли
источник
0

Ответ @ sdbrain в 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
источник
-1

В Swift 3.01 с использованием WKWebView:

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

Это приспосабливается к некоторым более тонким изменениям синтаксиса в 3.01 и сохраняет структуру каталогов на месте, чтобы вы могли встраивать связанные файлы HTML.

Бентли Бобо
источник
Разве префикс NS не пропал для ключевых типов фундаментов начиная с 3.x? Это помогло мне, спасибо! let localURL = URL.init(fileURLWithPath: Bundle.main.path(forResource: "index", ofType: "html", inDirectory: "mapa_procesos")!) webView.loadRequest(URLRequest(url: localURL))
Эдуардо Гомес