WKWebView не загружает изображения и CSS с помощью loadHTMLString (_, baseURL :)

Рекомендация Apple :

В приложениях, запущенных в iOS 8 и более поздних версиях, используйте класс WKWebView вместо использования UIWebView.

Таким образом, я заменил своего старого доброго UIWebViewновым блестящим . Но то, что я считал простым упражнением (просто замена классов и замена методов делегата), оказалось настоящим беспорядком.loadHTMLString(String, baseURL: URL?)

Эта проблема

Когда я загружаю HTML-строку, используя

htmlString

веб-просмотр загружает и отображает чистый HTML, но он не загружает изображения или файлы CSS, на которые ссылаются внутриhtmlString .

Это происходит только на реальном устройстве !
В Simultor все ссылочные ресурсы загружаются правильно.

имитатор Реальное устройство

пример

Я определил простой класс контроллера:let imageName = "image.png" let libraryURL: URL // The default Library URL var htmlString: String { return "<html> ... <img src="(imageName)" /> ... </html>" // "..." represents more valid HTML code incl. header and body tags }

let imageURL = libraryURL.appendingPathComponent(imageName)

Изображение сохраняется в корневой папке библиотеки, поэтому его URL-адрес:

htmlString

Теперь я загружаю веб-представление:webView.loadHTMLString(htmlString, baseURL: libraryURL)

baseURL

и он не загружает изображение, даже если WKWebViewоно установлено правильно.

Идеи для решения

  1. Возможно loadFileURL(URL, allowingReadAccessTo: URL), проблема с решением относительных путей, поэтому моя первая идея заключалась в том, чтобы вместо этого использовать абсолютные пути внутри строки HTML.
    >? Не работает.

  2. Два ответа на другое сообщение SO предложили использовать
    loadHTMLString(...)
    вместо WKWebViewработы в iOS 9+.
    >? Это работает.

Однако я не могу использовать решение 2, потому что мои файлы HTML зашифрованы, а дешифрованные файлы не должны храниться на диске.

Вопрос

Есть ли способ , чтобы загрузить местные ресурсы , такие как изображения и стили , используя WKWebView«S

loadHTMLString(String, baseURL: URL?)

функционировать? Или все еще ошибка в iOS 9+?

(Я просто не могу поверить, что Apple предлагает и рекомендует использовать веб-представление, которое не может загружать какой-либо локальный веб-контент из HTML-строки!)

ios,css,swift,image,wkwebview,

26

Ответов: 8


9
+50

Не смотря на ваш фактический проект, трудно дать некоторые рекомендации о процентах.

Тем не мение:

class ViewController: UIViewController {

    var webView = WKWebView()

    override func viewDidLoad() {
        super.viewDidLoad()
        webView.translatesAutoresizingMaskIntoConstraints = false
        let views = [
            "webView" : webView
        ]
        view.addSubview(webView)
        var constraints = NSLayoutConstraint.constraintsWithVisualFormat("H:|[webView]|", options: [.AlignAllLeading, .AlignAllTrailing], metrics: nil, views: views)
        constraints.appendContentsOf(NSLayoutConstraint.constraintsWithVisualFormat("V:|[webView]|", options: [.AlignAllTop, .AlignAllBottom], metrics: nil, views: views))
        NSLayoutConstraint.activateConstraints(constraints)

        let path = NSBundle.mainBundle().pathForResource("ios - WKWebView fails to load images and CSS using loadHTMLString(_, baseURL_) - Stack Overflow", ofType: "htm")
        let url = NSURL(fileURLWithPath: path!)
        webView.loadHTMLString(try! String(contentsOfURL: url), baseURL: url.URLByDeletingLastPathComponent)

        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

Я думаю, что ключевым моментом здесь является baseUrlпараметр, вы должны его правильно настроить. В моем случае я использовал URL-адрес html без последнего компонента пути, например, содержащую папку. Это отлично работает как на устройстве, так и на симуляторе - снимите снимок устройства. Я загрузил образец проекта в https://github.com/soxjke/WKWebViewTest, чтобы вы могли взглянуть (я удалил кодовую информацию из git)

Снимок устройства

Итак, для recap - метод работает, функциональность работает, просто вы делаете с ней что-то не так. Чтобы помочь вам понять, что не так с вашими решениями, я добавлю несколько предложений: 1. Помните, что файловая система симулятора нечувствительна к регистру , файловая система устройства чувствительна к регистру . Поэтому, если у вас есть имена файлов в html в нижнем регистре - это не будет работать на устройстве. 8fFsD.png != 8ffsd.png 2. Помните, что при копировании ресурсов XCode игнорирует структуру вашей папки. Поэтому, если ваш html имеет <img src="./img/1.png">и ваш проект XCOde имеет структуру папок, такую ??как

test.htm

img/

    1.png 
    2.png

После сборки он будет сплющен, поэтому test.htm и 1.png и 2.png будут находиться на одном уровне

test.htm
1.png 
2.png

Я почти уверен, что после проверки этих двух предположений вы получите этот метод.


3

Ну, вы должны иметь возможность использовать локальные изображения и файлы CSS (и файлы JavaScript в этом отношении) с помощью WKWebViews с уже найденной функцией. Я предполагаю, что проблема связана с вашей baseURLпеременной.

Обновление 7.5.2017:

Я полностью обновил код из другого SO-ответа, который был связан с моим ответом здесь. У меня есть рабочий проект loadHTMLString()и.loadFileURL()


2

Вы можете кодировать изображения base64 ... Я знаю, что это работает. Не уверен, что это будет подходящим для вашего случая использования.

Какой-то забавный, я просто столкнулся с этой проблемой, выполняя обратное - переход от base64 к файлам изображений.


2

Лично мне пришлось переключиться на использование XWebView, поскольку готовое поведение WKWebView не позволяет загружать локальные файлы. XWebView обманывает его, загружая локальный веб-сервер в фоновом режиме и направляя локальный трафик через него. (XWebView основан на WKWebView)

Кажется, немного переборщил, но это то, что мне в итоге пришлось делать.


1

Я тоже экспериментировал с подобными ограничениями, и проблема заключается в том, что пути не разрешаются, если не baseURLссылаются на пакет приложений. Это не работает, если вы, например, имеете что-то в документах приложения.

Редактировать: я подал радар для этого rdar: // 29130863

ИОС, CSS, быстрый, образ, wkwebview,
Похожие вопросы