WKWebView无法加载图像和CSS使用loadHTMLString(_,baseURL :)

苹果推荐 :

在iOS 8及更高版本中运行的应用程序中,使用WKWebView类而不是使用UIWebView。

因此,我用一个shiny的新WKWebView取代了我的旧UIWebView 。 但是,我认为是一个简单的练习(简单地交换类和replace委托方法)竟然是一个混乱。

问题

当我加载一个HTMLstring使用

 loadHTMLString(String, baseURL: URL?) 

Web视图加载并呈现纯HTML,但不加载任何在htmlString引用的图像或CSS文件

这只发生在一个真实的设备上
在Simultor中,所有引用的资源都被正确加载。

模拟器 真实的设备

我在我的视图控制器类中定义了一个简单的htmlString

 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 } 

该图像存储在根库文件夹中,因此其URL是:

 let imageURL = libraryURL.appendingPathComponent(imageName) 

现在我将htmlString加载到Web视图中:

 webView.loadHTMLString(htmlString, baseURL: libraryURL) 

即使baseURL设置正确,也不会加载图像。

一个解决scheme的想法

  1. 也许WKWebViewparsing相对path有问题,所以我的第一个想法是在HTMLstring内使用绝对path
    →❌不起作用。

  2. 对另一个SOpost的两个答案build议使用
    loadFileURL(URL, allowingReadAccessTo: URL)
    而不是loadHTMLString(...)在iOS 9 +中的作品。
    →✅那有效。

但是,我不能使用解决scheme2,因为我的HTML文件是encryption的,解密的文件不能存储在磁盘上。

有什么办法可以使用WKWebView来加载图片和样式等本地资源

 loadHTMLString(String, baseURL: URL?) 

function? 或者仍然是iOS 9 +中的一个错误?

(我简直不敢相信,苹果提供并推荐使用无法从HTMLstring内加载任何本地网页内容的网页视图?!)

没有看看你的实际项目,很难给出一些百分之百的肯定的build议。

然而:

 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参数,你应该正确地设置它。 在我的情况下,我已经使用HTML的URL没有最后一个path组件 – 例如包含文件夹。 这在设备和模拟器上正常工作 – 检查设备快照。 我已经上传示例项目到https://github.com/soxjke/WKWebViewTest,所以你可以看看(我已经从git删除codesigning信息&#xFF09;

设备快照

所以,回顾 – 方法正在工作,function正在工作,只是你做了一些错误的事情。 为了帮助您解决您的解决scheme,我会添加一些build议:1.请记住,模拟器文件系统不区分大小写 ,设备文件系统区分大小写 。 所以,如果你有你的文件名在HTML中小写 – 这不会在设备上工作。 2.记住,当复制资源时,XCode忽略你的文件夹结构。 所以如果你的html有<img src="./img/1.png">你的XCOde项目有像文件夹结构

 test.htm img/ 1.png 2.png 

构build之后,它会被压扁,所以test.htm和1.png和2.png将驻留在同一层

 test.htm 1.png 2.png 

我几乎可以肯定,在你validation了这两个假设后,你会得到这个方法的工作。

那么你应该能够使用WKWebViews和你已经find的函数来使用本地图像和CSS文件(和JavaScript文件)。 我的猜测是,问题是你的baseURLvariables。

更新7.5.2017:

我已经完全更新了另一个我的答案的代码,这个答案在我的答案中曾经被链接到这里。 我有一个工作项目的loadHTMLString().loadFileURL()

就个人而言,我必须切换到使用XWebView作为WKWebView的开箱即用的行为不允许加载本地文件。 XWebView通过在后台加载一个本地Web服务器并通过它指引本地stream量来欺骗它。 (XWebView是基于WKWebView的顶部)

似乎有点矫枉过正,但这是我最终不得不做的。

你可以base64编码的图像…我知道的作品。 不知道它是否适合您的使用情况。

有趣的是,我刚刚遇到了这个问题,而从base64编码转向图像文件。

我一直在尝试这个,也有类似的限制,问题似乎是path不解决,除非baseURL引用应用程序包。 例如,如果您在应用程序的文档中包含某些内容,则这种方法无效。

编辑:我已经为这个rdar提供了一个雷达:// 29130863

我能够重现类似的问题。 WKWebView加载我的图像,特别是如果它们位于远程,除了我的应用服务器。

对于不受SSL保护(http而不是https)的服务器,您可以按照以下方式设置您的info.plist

 App Transport Security Settings - Allow Arbitrary Loads in Web Content (Set to YES) - Allow Arbitrary Loads (Set to YES) 

问题实际上是在服务器上。 服务器应用程序是:

  • 将图像src从"http://IP-or-domain/uploads/file.jpg"更改为"../../uploads/file.jpg"

– 要么 –

  • 图像的src是"http://localhost/uploads/file.jpg" "http://127.0.0.1/uploads/file.jpg" 而不是 "http://YOUR-SERVER-IP-ADDRESS/uploads/file.jpg"

在这些情况下,实际的设备将无法find图像。 这只适用于iOS模拟器,因为虚拟设备与服务器和开发机器相同。 它可以读取LOCALHOST127.0.0.1

在我的服务器中,我使用了一个富文本编辑器(TinyMCE),它在检测到它是相同的源后自动删除IP地址。