在 App 中启用网页内容检查功能

网页检查器 (Web Inspector) 是一个强大的工具,允许您调试网页布局、单步执行 JavaScript、读取控制台日志消息等。在 macOS 上的 Safari 中,您可以使用网页检查器检查网页、扩展和 Service Worker。iOS 和 iPadOS 允许检查与 macOS 相同的内容,此外还支持主屏幕网页 App。

网页内容和 JavaScript 在 App 中有多种用途,从提供网页 UI 到使 App 可脚本化。以前,网页检查器支持检查直接从 Xcode 构建的用于本地开发的开发者配置 App,这意味着只要 App 是为开发而安装的,开发者就可以调试这些内容。然而,已发布的 App 版本无法检查动态网页内容或脚本,这使得开发者和用户不得不求助于更复杂的工作流程来获取原本可以通过网页检查器获得的信息。现在,同样的功能可以通过 WKWebViewJSContext 上的 API 获得。

如何启用检查?

在所有支持 WKWebViewJSContext 的平台上,新增了一个名为 isInspectable(在 Objective-C 中为 inspectable)的属性。它默认为 false,您可以将其设置为 true 以选择启用内容的可检查性。此决定是针对每个单独的 WKWebViewJSContext 做出的,以防止无意中为您不打算检查的视图或上下文启用此功能。因此,例如,要使 WKWebView 可检查,您需要:

Swift
let webConfiguration = WKWebViewConfiguration()
let webView = WKWebView(frame: .zero, configuration: webConfiguration)
webView.isInspectable = true
Objective-C
WKWebViewConfiguration *webConfiguration = [WKWebViewConfiguration new];
WKWebView *webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:webConfiguration];
webView.inspectable = YES;

对于 JSContext提供了匹配的 API,此外还为使用 JSGlobalContextRef 的开发者提供了 C API

Swift
let jsContext = JSContext()
jsContext?.isInspectable = true
Objective-C
JSContext *jsContext = [JSContext new];
jsContext.inspectable = YES;
C
JSGlobalContextRef jsContextRef = JSGlobalContextCreate(NULL);
JSGlobalContextSetInspectable(jsContextRef, true);

inspectable 属性可以在 WKWebViewJSContext 的生命周期中的任何时候更改。当网页检查器正在积极检查内容时禁用检查,网页检查器将自动关闭,并且将不再提供有关内容的任何信息。

为您的 App 启用检查后,您可以从 Safari 的“开发”菜单中,在当前电脑或连接设备对应的子菜单中检查它。对于 iOS 和 iPadOS,您还必须在“设置”App 中,在Safari > 高级 > 网页检查器下启用网页检查器。您不需要为模拟器启用网页检查器;它始终处于启用状态。了解更多关于启用网页检查器…

Develop Menu > Patrick's iPhone > Example App

我何时应考虑使内容可检查?

一个常见的场景是,在应用内网页浏览器中,您可能希望 WKWebView 的内容可检查。浏览器显示的是普通网页内容,当在 Safari 中加载时也是可检查的。能够检查这些视图中的内容对 App 开发者和网页作者都很有益,因为视图的大小可能与 Safari 不匹配,或者 App 开发者可能正在向视图中注入脚本以提供与其 App 的集成。

网页内容通常是动态的,由服务器而非 App 提供,并且会随时间轻松更改。不幸的是,并非所有问题都能或将会由能够访问您的 App 的开发者预配置副本的人进行调试。

JSContext 还可以实现在 App 中启用脚本功能,即客户提供脚本来增强 App。如果您的 App 的发布版本无法支持可检查性,您的客户可能无法调试他们编写的脚本。这使得客户更难使用您 App 的此功能。

为可检查的 JSContext 提供可读的名称

WKWebView 不同,WKWebView 会根据视图中当前加载的页面自动获得一个名称,而所有启用了 inspectableJSContext 都将在 Safari 的“开发”菜单中列为“JSContext”。我们建议为每个可检查的 JSContext 提供一个唯一的、人类可读的名称,以便您和您的客户更容易确定 JSContext 代表什么。例如,如果您的 App 代表用户运行不同的 JavaScript 片段,您应该根据上下文中运行的内容为每个 JSContext 命名。

API 可用于设置 JSContext 的用户可见名称

Swift
let jsContext = JSContext()
jsContext?.name = "Context name"
Objective-C
JSContext *jsContext = [JSContext new];
jsContext.name = @"Context name";
C
JSGlobalContextRef jsContextRef = JSGlobalContextCreate(NULL);
`JSGlobalContextSetName`(jsContextRef, JSStringCreateWithUTF8CString("Context name"));

使用旧版 macOS 和 iOS

对于链接到 macOS 13.3 和 iOS 16.4 之前的 SDK 的 App,WKWebViewJSContext 将继续遵循以前的行为,即在从 Xcode 构建以进行调试时始终可检查。

支持旧版 macOS 和 iOS 但链接到最新 SDK 的 App 将不会获得旧的在调试构建中所有内容都可检查的行为,以避免混淆客户将可检查哪些内容、不可检查哪些内容。针对旧操作系统版本但链接新 SDK 的 App 可以在支持它的操作系统版本上条件性地使用此新 API。要条件性地保护 API 的使用:

Swift
if #available(macOS 13.3, iOS 16.4, tvOS 16.4, *) {
    webView.isInspectable = true
}
Objective-C
if (@available(macOS 13.3, iOS 16.4, tvOS 16.4, *))
    webView.inspectable = YES;

您可以访问 developer.apple.com 了解更多关于保护新 API 使用的信息。

反馈

在您探索这个新 API 的过程中,如果您遇到问题,请提供反馈以帮助我们。对于使用此新 API 时遇到的问题,请通过您的 Mac、iPhone 或 iPad 提交反馈。反馈助手将收集所需信息,以帮助我们了解情况。如果您在检查 App 内容后遇到网页检查器本身的问题,请在 bugs.webkit.org 上提交 Bug。

另外,我们乐于倾听您的意见。您可以在 Mastodon 上找到我们:@patrickangle@hachyderm.io@jensimmons@front-end.social@jondavis@mastodon.social

注意:从网页检查器参考文档中了解更多关于网页检查器的信息。