在我的Swift iOS应用程序中,我想从远程服务器下载一些动态HTML页面,将它们保存在文档目录中,并从文档目录中显示这些页面.

我用这个来加载页面:

var appWebView:WKWebView?
...
appWebView!.loadRequest(NSURLRequest(URL: NSURL(fileURLWithPath: htmlPath)))

一切都在模拟器上运行,但当我换到真正的手机时,它只显示了一个空白页.然后我用Safari连接到应用,发现它抱怨"加载资源失败".

然后我试着先读htmlPath页的内容,然后使用

appWebView!.loadHTMLString()

加载页面.当HTML页面很简单时,它就工作了.但是,如果HTML引用了其他内容,也就是文档目录中的JavaScript文件(绝对路径为<script src="file:////var/mobile/Containers/Data/Application/762035C9-2BF2-4CDD-B5B1-574A0E2B0728/Documents/xxxxx.js">),它将无法加载.

有人知道为什么会发生这种情况,以及如何解决这个问题吗?

更多信息:

  • XCode版本:7.3.1
  • 部署目标:8.1(我也try 过使用9.3,但没有帮助.)

推荐答案

这是我在一个项目(iOS 10,Swift 3)中加载本地文件时使用的简化版本.根据Raghuram和Fox5150在 comments 中的要求,在iOS 10.3.1和iPhone 7+上再次测试后,我只有updated my code (7.5.2017)个.

我刚刚创建了一个全新的项目,这是文件夹 struct :enter image description here

Update 19.04.2018:增加了一个新功能来下载.使用HTML、CSS、JS文件压缩,在/Documents/(Alamofire+zip)中解压缩,然后将这些文件加载到webView中.你也可以在GitHub sample project中找到它.再一次,请随意使用fork&;明星!:)

Update 08.02.2018:最终添加了一个GitHub sample project,其中还包括一个本地JavaScript文件.请随意使用fork&;明星!:)

带有webView的版本1.loadFileURL()

视图控制器.敏捷的

import UIKit
import WebKit
class ViewController: UIViewController, WKNavigationDelegate {
    override func viewDidLoad() {
        super.viewDidLoad()
        let webView = WKWebView()
        let htmlPath = Bundle.main.path(forResource: "index", ofType: "html")
        let htmlUrl = URL(fileURLWithPath: htmlPath!, isDirectory: false)
        webView.loadFileURL(htmlUrl, allowingReadAccessTo: htmlUrl)
        webView.navigationDelegate = self
        view = webView
    }
}

带有webView的版本2.loadHTMLString()

视图控制器.敏捷的

import UIKit
import WebKit
class ViewController: UIViewController, WKNavigationDelegate {
    override func viewDidLoad() {
        super.viewDidLoad()
        let webView = WKWebView()
        let htmlPath = Bundle.main.path(forResource: "index", ofType: "html")
        let folderPath = Bundle.main.bundlePath
        let baseUrl = URL(fileURLWithPath: folderPath, isDirectory: true)
        do {
            let htmlString = try NSString(contentsOfFile: htmlPath!, encoding: String.Encoding.utf8.rawValue)
             webView.loadHTMLString(htmlString as String, baseURL: baseUrl)
        } catch {
            // catch error
        }
        webView.navigationDelegate = self
        view = webView
    }
}

Gotchas to look out for:

  • Make sure that your local html/js/css files are in Project -> Target -> Build Phases -> Copy Bundle Resources
  • 确保你的html文件不引用相对路径,例如css/styles.css,因为iOS会使你的文件 struct 和样式扁平化.css将与索引处于同一级别.所以写<link rel="stylesheet" type="text/css" href="styles.css">

Given the 2 versions and the gotchas here are my html/css files from the project:

网络/索引.html

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
    <title>Offline WebKit</title>
    <link rel="stylesheet" type="text/css" href="styles.css">
  </head>
  <body>
    <h1 id="webkit-h1">Offline WebKit!</h1>
  </body>
</html>

css/web样式.css

#webkit-h1 {
  font-size: 80px;
  color: lightblue;
}

如果有人想要一个GitHub示例项目,请在 comments 部分告诉我,我会上传它.

Swift相关问答推荐

Swift Tree实现中的弱var

多个提取来计算核心数据中的记录

SwiftUI—如何识别单词并获取视觉中的位置

如何禁用MacOS上SwiftUI中按钮周围的聚焦环(或高亮显示)?

RealityKit(VisionOS)中的PhysicBodyComponent和DragGesture

如何在visionOS中定制悬停效果区域

是否在字符串属性上搜索数组和子数组?

仅当单击UIButton时才调用计时器函数

有没有一种方法可以访问封闭实例ObservableObject以从属性包装器中的任何位置调用objectWillChange.send()

ForEach within List:模式的好处?

如何裁剪图像 3:4 ?迅速

Swift 根据总值将数组拆分为块

RealityKit – 无法加载 ARView(发现为零)

如何在 Swift 中返回 Task 中定义的变量

如何有条件地格式化 SwiftUI 代码

Swift 2.0 方法不能标记为@objc,因为参数的类型不能在 Objective-C 中表示

在 Swift 中将两个字节的 UInt8 数组转换为 UInt16

我可以在 Swift 中为泛型类型 T 分配默认类型吗?

UICollectionView 自定义单元格在 Swift 中填充宽度

Facebook SDK 4.0 IOS Swift 以编程方式注销用户