You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在WKWebView中本地加载iframe?附HTML页面实现需求

用WKWebView加载本地HTML及本地iframe的解决方案

嘿,我来帮你搞定这两个问题!下面分两部分详细说明:

一、加载本地HTML页面(含Bootstrap等资源)

首先要确保你的HTML文件、css/js等资源都正确添加到Xcode项目中,勾选「Copy items if needed」,同时在项目的「Build Phases」→「Copy Bundle Resources」里能看到这些文件。

1. 配置WKWebView权限

本地文件加载需要开启允许文件URL访问其他本地资源的权限,否则Bootstrap这类依赖外部文件的资源会加载失败,代码如下:

import WebKit

// 创建WKWebView配置
let webViewConfig = WKWebViewConfiguration()
// 关键:允许文件URL访问其他本地文件
webViewConfig.preferences.setValue(true, forKey: "allowFileAccessFromFileURLs")

// 创建WKWebView并添加到视图
let webView = WKWebView(frame: view.bounds, configuration: webViewConfig)
webView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
view.addSubview(webView)

2. 加载本地HTML文件

假设你的主HTML文件名为AppendixB1.html,放在项目的WebContent子目录下(和css文件夹同级),用loadFileURL方法加载,同时设置允许访问的目录:

guard let htmlFileURL = Bundle.main.url(
    forResource: "AppendixB1",
    withExtension: "html",
    subdirectory: "WebContent"
) else {
    print("找不到本地HTML文件,请检查文件名和路径")
    return
}

// 允许访问HTML文件所在的整个目录,这样css/js等相对路径资源能正常加载
webView.loadFileURL(htmlFileURL, allowingReadAccessTo: htmlFileURL.deletingLastPathComponent())

注意:你HTML里的../../css/bootstrap.min.css路径要对应实际文件结构,比如如果HTML在WebContent/appendices下,css在WebContent/css,那相对路径应该是../css/bootstrap.min.css,确保路径正确才能加载到资源。

二、本地加载iframe的方法

加载本地iframe的核心还是确保权限开启,同时正确设置iframe的src路径:

1. 静态加载本地iframe内容

如果iframe的内容是另一个本地HTML文件,直接在主HTML里用相对路径设置src即可:

<!-- 假设主HTML在WebContent/appendices下,iframe的HTML在WebContent/iframes/iframe1.html -->
<iframe src="../iframes/iframe1.html" width="100%" height="600" frameborder="0"></iframe>

只要之前开启了allowFileAccessFromFileURLs,这个iframe就能正常加载本地内容。

2. 动态加载本地iframe内容

如果需要通过代码动态设置iframe的本地内容,有两种方式:

方式一:修改iframe的src为本地文件URL

// 先获取iframe的本地文件URL
guard let iframeURL = Bundle.main.url(
    forResource: "iframe1",
    withExtension: "html",
    subdirectory: "WebContent/iframes"
) else { return }

// 把URL转为相对路径(相对于主HTML的目录),或者直接用fileURL的字符串
webView.evaluateJavaScript("document.getElementById('my-iframe').src = '\(iframeURL.absoluteString)'") { result, error in
    if let err = error {
        print("设置iframe失败:\(err.localizedDescription)")
    }
}

方式二:直接加载HTML字符串到iframe

如果iframe的内容是动态生成的HTML字符串,可以结合baseURL来加载本地资源:

let iframeHTML = """
<!DOCTYPE html>
<html>
<head>
    <link href="../css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    <h3>本地iframe内容</h3>
</body>
</html>
"""

// baseURL设为主HTML所在的目录,这样iframe里的相对路径资源能正常加载
guard let baseURL = Bundle.main.url(forResource: "AppendixB1", withExtension: "html", subdirectory: "WebContent/appendices")?.deletingLastPathComponent() else { return }

webView.evaluateJavaScript("""
    const iframe = document.getElementById('my-iframe');
    const doc = iframe.contentDocument || iframe.contentWindow.document;
    doc.open();
    doc.write(`\(iframeHTML)`);
    doc.close();
""")

关键注意事项

  • 所有本地资源必须被正确添加到Bundle中,否则会找不到文件;
  • 相对路径一定要对应实际的文件结构,避免路径错误;
  • allowFileAccessFromFileURLs是必须开启的,否则本地iframe和外部资源都会加载失败;
  • iOS 14及以上版本,不需要额外的隐私权限,只要配置正确就能正常加载。

内容的提问来源于stack exchange,提问作者dperazzolo

火山引擎 最新活动