移动/游戏
在 iOS 26+ SwiftUI 应用中嵌入和控制…
面向 iOS 26+/iPadOS 26/macOS 26/visionOS 26 的 SwiftUI 应用,需要内嵌网页、加载本地 HTML、执行 JavaScript 或自定义导航策略时,使用原生 WebView 与 WebPage API。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 59/100 ×0.15
适用场景
在 iOS 26+ SwiftUI 应用特定
解决思路
- 按需求选择最窄的容器:SwiftUI 内嵌自有 Web 内容用 WebView + WebPage;iOS/iPadOS 模态 Safari 浏览用 SFSafariViewController;macOS/visionOS 跳出浏览用 openURL/默认浏览器;OAuth 或第三方登录用 ASWebAuthenticationSession;需回退到 iOS 26 以下或使用旧版独有 WebKit 功能时用 WKWebView。
- 仅需渲染 URL 且由 SwiftUI 状态驱动导航时,使用简单的 WebView(url:) 形式。
- 需要直接加载请求、观察状态、调用 JavaScript 或自定义导航行为时,创建 WebPage。
- 一个 WebPage 同一时间只能关联一个 WebView;多个可见 WebView 必须各自创建独立的 WebPage 实例。
- 用 WebPage 的加载入口:load(URLRequest)、load(URL)、load(html:baseURL:)、load(_:mimeType:characterEncoding:baseURL:)。
- 用 WebPage 的可观察属性驱动 UI:title、url、isLoading、estimatedProgress、currentNavigationEvent、backForwardList。
- 需要响应每次导航时,遍历 page.navigations 序列,而不是只检查单个属性。
- 用 WebPage.NavigationDeciding 实现 decidePolicy(for:preferences:),根据请求或响应允许、取消或定制导航:保留自有域名在内嵌视图、取消外部域名并用 openURL 跳出、拦截特殊回调 URL、调整 NavigationPreferences。
- 用 callJavaScript(_:arguments:in:contentWorld:) 执行 JavaScript:传入函数体而非包裹的函数声明或调用表达式,Swift 提供的值通过 arguments 字典传递,避免把不可信字符串插值进脚本。
- 处理 JavaScript 返回值时做防御性转换:无显式 return 得到 nil,显式 JavaScript null 返回 NSNull,需按实际 Swift 类型转换。
- 需要 JS 到原生的粗粒度信号时,可用自定义导航或回调 URL 模式作为变通,但需注明这不是 WKScriptMessageHandler 的一对一替代。
- 需要打包 HTML、离线文档或应用自有资源时,用 WebPage.Configuration 和 URLSchemeHandler 注册自定义 scheme(如 docs://),加载本地内容。
- 按需使用 WebView 修饰符:webViewBackForwardNavigationGestures(_:)、findNavigator(isPresented:)、webViewScrollPosition(_:)、webViewOnScrollGeometryChange(...);多页浏览时启用前进/后退手势,文档类内容加 Find in Page,有侧边栏或目录时才同步滚动位置。
- 遵循 HIG:适当支持前进/后退导航,但不要把应用内 WebView 变成通用浏览器。
- 遍历 page.navigations 时使用 for try await 并处理抛出的导航错误,因为导航失败会通过抛错终止序列。
- 每个可见的 WebView(page) 拥有独立的 WebPage。
- 仅在真实应用自有资源时使用自定义 URL scheme,服务器托管页面优先用标准 HTTPS。
- SFSafariViewController 仅限 iOS/iPadOS 的 Safari 风格模态浏览;macOS 和 visionOS 的跳出流程使用平台默认浏览器行为。
- 让 Web 体验提供聚焦的原生价值,而不是做成薄浏览器外壳。
- 回退到 WKWebView 必须有部署目标或缺失 API 的正当理由。
适用边界 · 注意事项
- 不要用内嵌 WebView 处理 OAuth,应使用 ASWebAuthenticationSession。
- 不要在 iOS 26+ SwiftUI 应用中默认使用 WKWebView 包装,除非部署目标或缺失 API 需要。
- 不要把 callJavaScript 当作 WKScriptMessageHandler 的直接替代,也不要把可调用的 JavaScript 包装传给 callJavaScript。
- 不要为应通过 HTTPS 加载的内容使用自定义 URL scheme。
- 不要把同一个 WebPage 绑定到多个可见 WebView。