browserenginekit

browserenginekit

热门

使用 BrowserEngineKit 构建第三方(非 WebKit)浏览器引擎。适用于在支持地区开发 iOS/iPadOS 非 WebKit 浏览器引擎、管理网页内容/渲染/网络扩展进程、配置 GPU 及网络进程能力、校验第三方引擎的设备适用资格,或核查 BrowserEngineKit 的 Entitlements 权限与 Info.plist 配置。

967Star
49Fork
更新于 2026/7/31
SKILL.md
只读
名称
browserenginekit
描述

使用 BrowserEngineKit 构建第三方(非 WebKit)浏览器引擎。适用于在支持地区开发 iOS/iPadOS 非 WebKit 浏览器引擎、管理网页内容/渲染/网络扩展进程、配置 GPU 及网络进程能力、校验第三方引擎的设备适用资格,或核查 BrowserEngineKit 的 Entitlements 权限与 Info.plist 配置。

BrowserEngineKit

用于在 iOS 和 iPadOS 上构建第三方(非 WebKit)渲染引擎浏览器的开发框架。为实现了自定义 HTML/CSS/JavaScript 引擎的浏览器应用提供进程隔离、XPC 通信、能力管理(Capability Management)以及系统级集成支持。示例代码适用于 Swift 6.3 及当前版本的 Apple SDK。

BrowserEngineKit 属于专项开发框架。第三方浏览器引擎仅能在通过 Apple 批准的 Entitlement 配置文件且具备支持地区设备资格的环境下运行。其中欧盟地区支持覆盖 iOS 17.4+ 与 iPadOS 18+ 的合规用户;日本地区支持从 iOS 26.2 起引入,并对浏览器应用提出了明确的 PAC/MIE 安全要求。开发与测试可以在任何地区进行。配套框架 BrowserEngineCore(底层原语)与 BrowserKit(资格校验、数据传输)共同支撑整体工作流。

目录

概述与适用资格

设备资格校验

使用 BrowserKit 框架中的 BEAvailability 来校验设备是否具备运行第三方浏览器引擎的资格。BEAvailability 适用于 iOS/iPadOS 18.4+:

import BrowserKit

do {
    let eligible = try await BEAvailability.isEligible(for: .webBrowser)
    guard eligible else { return /* 降级处理或向用户说明 */ }
    // 设备支持第三方浏览器引擎
} catch {
    // 处理资格查询失败的情况
}

资格取决于设备所在的地区与系统版本。切勿硬编码地区判断逻辑,请务必依赖系统 API。

版本可用性基线:进程相关 API 要求 iOS/iPadOS 17.4+,BEDownloadMonitor 要求 iOS 18.2+,.revision2 限制沙盒要求 iOS 26+,RenderingExtensionFeature.coreML 要求 iOS 26.2+。

Entitlements 权限配置

浏览器主应用(宿主)

主应用需要配置以下两项 Entitlement:

Entitlement Purpose
com.apple.developer.web-browser 允许申请成为默认浏览器
com.apple.developer.web-browser-engine.host 允许加载第三方引擎扩展

两项权限均需向 Apple 申请,具体申请流程因地区而异。

扩展程序 Entitlements

每个 Extension Target 都需要将其对应类型的 Entitlement 设置为 true

Extension Type Entitlement
Web content(网页内容) com.apple.developer.web-browser-engine.webcontent
Networking(网络) com.apple.developer.web-browser-engine.networking
Rendering(渲染) com.apple.developer.web-browser-engine.rendering

可选 Entitlements

Entitlement Extension Purpose
com.apple.security.cs.allow-jit Web content 允许对脚本进行 JIT 编译
com.apple.developer.kernel.extended-virtual-addressing Web content 配合 JIT 使用的扩展虚拟地址空间(必需)
com.apple.developer.memory.transfer_send Rendering 发送内存归属归因(Memory Attribution);值为主应用的 Bundle ID
com.apple.developer.memory.transfer_accept Web content 接收内存归属归因;值为主应用的 Bundle ID
com.apple.developer.web-browser-engine.restrict.notifyd Web content 限制对通知守护进程(notifyd)的访问

嵌入式浏览器引擎(非浏览器应用)

非浏览器应用若需要嵌入第三方引擎来实现应用内浏览,应使用不同的 Entitlement:

Entitlement Purpose
com.apple.developer.embedded-web-browser-engine 启用嵌入式引擎
com.apple.developer.embedded-web-browser-engine.engine-association 声明引擎归属权

engine-association 自 iOS/iPadOS/Mac Catalyst 26.2 起可用。如果你拥有该引擎,设为 first-party;若使用其他开发者开发的引擎,设为 third-party。嵌入式引擎仅支持 arm64 架构(不支持 arm64e),无法包含浏览器扩展,且不支持 JIT 编译。

日本地区特定要求

在日本分发的浏览器应用要求 iOS 26.2+。应用必须采用 Apple 针对日本地区列出的最新安全缓解措施,包括在相关分配器和扩展进程中启用指针身份验证码(PAC)和内存完整性强制执行(MIE)。请通过 com.apple.security.hardened-process.checked-allocations 开启硬件内存标记;Apple 强烈建议在欧盟地区也开启此配置。

系统架构

使用 BrowserEngineKit 构建的浏览器由运行在独立进程中的四个组件构成:

Host App (UI, coordination) 主应用(UI 与协同调度)
  |
  |-- XPC --> Web Content Extension 网页内容扩展(HTML 解析、JS、DOM)
  |-- XPC --> Networking Extension 网络扩展(URLSession、Socket)
  |-- XPC --> Rendering Extension 渲染扩展(Metal、GPU、媒体处理)

主应用负责启动并管理所有扩展。扩展之间无法直接启动其他扩展。扩展之间的相互通信必须通过由主应用撮合代理的匿名 XPC 端点(Anonymous XPC Endpoints)来进行。

引导启动序列

  1. 主应用启动网页内容扩展、网络扩展和渲染扩展
  2. 主应用分别建立与各个扩展的 XPC 连接
  3. 主应用向网络扩展和渲染扩展请求匿名 XPC 端点
  4. 主应用通过引导消息(Bootstrap Message)将这两个端点发送给网页内容扩展
  5. 网页内容扩展使用端点直接与网络扩展及渲染扩展建立连接

该架构遵循最小权限原则:网页内容扩展虽然需要处理不可信的数据,但它没有任何直接访问操作系统资源的权限。

进程管理

启动扩展

主应用中每种扩展类型都对应一个进程管理类:

import BrowserEngineKit

// 网页内容扩展(每个 Tab 或 iframe 对应一个实例)
let contentProcess = try await WebContentProcess(
    bundleIdentifier: nil,
    onInterruption: {
        // 处理崩溃或被系统打断的情况
    }
)

// 网络扩展(通常全局只有一个实例)
let networkProcess = try await NetworkingProcess(
    bundleIdentifier: nil,
    onInterruption: {
        // 处理被打断的情况
    }
)

// 渲染 / GPU 扩展(通常全局只有一个实例)
let renderingProcess = try await RenderingProcess(
    bundleIdentifier: nil,
    onInterruption: {
        // 处理被打断的情况
    }
)

bundleIdentifier 传入 nil 表示使用默认的 Extension Target。当扩展崩溃或被操作系统强行终止时,会触发 onInterruption 回调。

创建 XPC 连接

let connection = try contentProcess.makeLibXPCConnection()
// 使用 connection 进行进程间消息通信

每种进程类型均提供 makeLibXPCConnection() 方法,用于创建通信所需的 xpc_connection_t

停止扩展

contentProcess.invalidate()

调用 invalidate() 后,该进程对象上的所有后续方法调用均不再生效。

扩展类型

Web Content 扩展

用于承载浏览器引擎的 HTML 解析器、CSS 引擎、JavaScript 解释器和 DOM 树。遵循 WebContentExtension 协议以处理传入的 XPC 连接:

import BrowserEngineKit

@main
struct MyWebContentExtension: WebContentExtension {
    func handle(xpcConnection: xpc_connection_t) {
        // 在 connection 上配置消息处理逻辑
    }
}

在扩展的 EXAppExtensionAttributes 中通过 WebContentExtensionConfiguration 进行配置。

Networking 扩展

使用 URLSession 或 Socket API 处理所有网络请求。单一实例即可为所有标签页提供服务:

import BrowserEngineKit

@main
struct MyNetworkingExtension: NetworkingExtension {
    func handle(xpcConnection: xpc_connection_t) {
        // 处理网络请求消息
    }
}

通过 NetworkingExtensionConfiguration 进行配置。

Rendering 扩展

通过 Metal 访问 GPU,负责视频解码、图层合成以及复杂渲染。通常全局单个实例即可服务整个浏览器:

import BrowserEngineKit

@main
struct MyRenderingExtension: RenderingExtension {
    init() {
        if #available(iOS 26.2, macOS 26.2, *) {
            enableFeature(.coreML)
        }
    }

    func handle(xpcConnection: xpc_connection_t) {
        // 处理渲染指令
    }
}

通过 RenderingExtensionConfiguration 进行配置。

Capabilities 能力管理

为扩展授予对应能力,以便操作系统对其进行合理的资源与调度管理:

// 为扩展授予前台调度优先级
let grant = try contentProcess.grantCapability(.foreground)

// ... 扩展在前台执行任务 ...

// 任务完成后予以释放
grant.invalidate()

可用 Capabilities

Capability Use Case
.foreground 活跃标签页渲染、当前可见内容
.background 后台任务、资源预加载
.suspended 极低活动量、等待清理释放
.mediaPlaybackAndCapture(environment:) 音视频播放、摄像头/麦克风采集

媒体环境(Media Environment)

对于媒体相关能力,可创建绑定到指定页面 URL 的 MediaEnvironment。该环境支持使用 AVCaptureSession 访问摄像头和麦克风,并且支持 XPC 序列化,方便跨进程传输:

let mediaEnv = MediaEnvironment(webPage: pageURL)
let grant = try contentProcess.grantCapability(
    .mediaPlaybackAndCapture(environment: mediaEnv)
)
try mediaEnv.activate()
let captureSession = try mediaEnv.makeCaptureSession()

可见性传递(Visibility Propagation)

将可见性传递交互绑定至浏览器视图,以便扩展精准获知内容何时在屏幕上显示。WebContentProcessRenderingProcess 均提供了 createVisibilityPropagationInteraction() 方法。

图层宿主与视图协同

渲染扩展会将内容绘制到 LayerHierarchy 中,主应用则通过 LayerHierarchyHostingView 展示其内容。相关句柄通过 XPC 传输。使用 LayerHierarchyHostingTransactionCoordinator 可在多进程间实现图层更新的原子化同步。

如需查看详细的图层宿主示例和事务协同机制,请参阅 references/browserenginekit-patterns.md

文本交互

在自定义文本视图上接入 BETextInput 协议,以对接 UIKit 文本系统。这将直接启用标准的文本选择、自动更正、听写以及键盘交互支持。

关键集成点:

  • 通过 asyncInputDelegate 向系统同步文本变更
  • 通过 handleKeyEntry(_:completionHandler:) 处理键盘事件
  • 使用 BETextInteraction 支持选择手势、编辑菜单与上下文菜单
  • 使用 BEScrollViewBEScrollViewDelegate 实现自定义滚动处理

如需查看具体的文本交互实现细节,请参阅 references/browserenginekit-patterns.md

沙盒与安全

严格限制沙盒(Restricted Sandbox)

在完成初始化后,应用严格限制沙盒来锁定内容扩展:

// 在 Web Content 扩展完成初始化设置后:
if #available(iOS 26.0, macOS 26.0, *) {
    applyRestrictedSandbox(revision: .revision2)
} else {
    applyRestrictedSandbox(revision: .revision1)
}

这将移除扩展在启动阶段使用过但后续不再需要的资源访问权限。请使用最新的可用 Revision 以获得最高强度的安全限制。

JIT 编译

执行 JavaScript JIT 编译的 Web Content 扩展必须使用 BrowserEngineKit 的带见证凭证 API(witnessed APIs)来进行页面内存状态转换:

import BrowserEngineCore

be_memory_inline_jit_restrict_rwx_to_rw_with_witness(...)
// 写入生成的代码
be_memory_inline_jit_restrict_rwx_to_rx_with_witness(...)

Requires the `com.appl

<!-- truncated for translation batch; full body continues in source -->