SuperSDK iOS 接入文档
版本:dev | 稳定性:开发中 — 内容随时变更,仅供内部参考
SuperSDK iOS 版提供与 Android 版功能对齐的 WebView 容器能力,包括 JSBridge、离线包、云控配置等。
| 项目 | 要求 |
|---|---|
| iOS 版本 | iOS 14.0+ |
| Swift 版本 | Swift 5.0+ |
| WebView | WKWebView |
| 架构支持 | arm64(真机)、arm64 + x86_64(模拟器) |
方式一:远程 Swift Package Manager(第三方模板推荐)
Section titled “方式一:远程 Swift Package Manager(第三方模板推荐)”第三方宿主和模板工程优先使用远程 SPM 包。发布时需要同时提供:
| 环境变量 | 说明 |
|---|---|
SPM_PACKAGE_URL | 承载 generated Package.swift 的 HTTPS Git 仓库地址 |
SPM_BINARY_BASE_URL | 承载 SuperSDK-<VERSION>.xcframework.zip 的 HTTPS CDN 根地址 |
dependencies: [ .package(url: "<SPM_PACKAGE_URL>", exact: "<VERSION>")]发布脚本会生成:
packages/ios-sdk/release/├── SuperSDK-<VERSION>.xcframework.zip├── spm-package/Package.swift└── spm-release.jsonspm-release.json、spm-package/Package.swift 和 zip 文件 checksum 必须一致。只有 SPM_PACKAGE_URL 与 SPM_BINARY_BASE_URL 都配置为真实 HTTPS 地址后,才能作为公网远程 SPM 包发布。
方式二:XCFramework 手动集成
Section titled “方式二:XCFramework 手动集成”- 从本目录获取
SuperSDK.xcframework - 将
SuperSDK.xcframework拖入 Xcode 项目 - 在 Target > General > Frameworks, Libraries, and Embedded Content 中设置为 Embed & Sign
SuperSDK.xcframework/├── ios-arm64/ # 真机 (arm64)└── ios-arm64_x86_64-simulator/ # 模拟器 (arm64 + x86_64)方式三:本地 Swift Package Manager(SDK 开发调试)
Section titled “方式三:本地 Swift Package Manager(SDK 开发调试)”dependencies: [ .package(path: "path/to/SuperSDK")]方式四:源码集成
Section titled “方式四:源码集成”将 SuperSDK/ 目录作为本地 Swift Package 引入项目。
必要的 Info.plist 配置
Section titled “必要的 Info.plist 配置”宿主必须在 App 的 Info.plist 填写 NSMicrophoneUsageDescription(SDK / xcframework 不会替宿主带上这条)。H5 getUserMedia 麦克风依赖该用途说明;缺或空字符串时,iOS 15+ 容器 Deny、不启动采集(避免 TCC 因缺说明杀进程)。
<key>NSMicrophoneUsageDescription</key><string>网页需要使用麦克风进行语音输入或录音。</string>createPageView() / createPageViewController(url:) 无需再包一层 WKUIDelegate。iOS 15+ SuperWebView 已实现 requestMediaCapturePermissionFor(microphone 有说明则 Prompt;camera 恒 Prompt;cameraAndMicrophone 无 mic 说明则 Deny)。iOS 14 无该 API,保持系统默认。getUserMedia 需 https 安全源;离线命中改写的 super-offline:// 通常不是 secure context。
注意:模块名为
SuperSDK(import SuperSDK),入口类为SuperSDKManager。 用法SuperSDKManager.shared.xxx。(iOS 入口类名与 Android 的SuperSDK不一致,详见发布说明。)
在 AppDelegate 中初始化 SDK:
import SuperSDK
@mainclass AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Replace ab12cd34 with the real spid issued by the SuperSDK console. try! SuperSDKManager.shared.initialize( spid: "ab12cd34", provider: MySDKProvider() )
return true }}参数说明:
| 参数 | 类型 | 说明 |
|---|---|---|
| spid | String | 控制台签发的 8 位小写字母/数字项目标识 |
| provider | SuperSDKProvider | 宿主实现的服务提供者 |
项目环境(API Environment)
Section titled “项目环境(API Environment)”项目环境对应控制台顶栏的 env(如 prod / staging),决定 SDK 拉取哪套云控配置(settings)以及埋点上报归属的环境。它不再是 initialize 参数,而是独立的运行时状态。
方法签名:public func setAPIEnvironment(_ environment: String) throws / public func getAPIEnvironment() -> String
// 设置项目环境(initialize 前后均可调用;非法值抛 SDKIdentityValidationError.invalidEnvironment 且不落地)try SuperSDKManager.shared.setAPIEnvironment("staging")
// 读取当前项目环境(未设置时返回 "prod",不要求已 initialize)let env = SuperSDKManager.shared.getAPIEnvironment()规则与行为:
- 取值限 1–10 位小写字母/数字(
^[a-z0-9]{1,10}$),不 trim、不做大小写转换 - SDK 不持久化该值:进程启动默认
prod,宿主如需记忆用户选择,需自行持久化并在启动后调用setAPIEnvironment - 运行时切换的副作用顺序:冲刷旧环境的存量上报事件 → 换值 → settings 清本地缓存并按新环境重拉 → 刷新存活 WebView 的 UA(仅影响后续导航)
- 切换后 settings 拉取自动带
env参数、上报basic_data.env与请求头X-Super-API-ENV均使用新值;H5 侧经getEnv()读到新值 - 该环境与
HostConfigService.sdkApiBaseUrls(API 域名)是不同维度:切环境不需要也不应该改 API 域名
实现 SuperSDKProvider
Section titled “实现 SuperSDKProvider”SuperSDKProvider 是宿主 App 向 SDK 提供能力的桥梁。所有方法均为可选实现(默认返回 nil)。
class MySDKProvider: SuperSDKProvider {
private let hostConfigService = MyHostConfigService()
func getHostConfigService() -> HostConfigService? { return hostConfigService }
func getEventService() -> EventService? { nil } func getLoginService() -> LoginService? { nil } func getHostMethodService() -> HostMethodService? { nil } func getNavigationService() -> NavigationService? { nil } func getNativeBlockService() -> NativeBlockProvider? { nil }}核心 API
Section titled “核心 API”// 方式 1: 创建 PageView 嵌入到自己的视图中let pageView = SuperSDKManager.shared.createPageView()view.addSubview(pageView)pageView.frame = view.boundspageView.load(url: "https://example.com")
// 方式 2: 创建 ViewController(推荐,内置导航栏和生命周期管理)let vc = SuperSDKManager.shared.createPageViewController(url: "https://example.com")navigationController?.pushViewController(vc, animated: true)
// 方式 3: 通过 PageController 打开全屏页面SuperSDKManager.shared.getPageController().openPage(url: "https://example.com")SuperPageDelegate - 页面事件监听
Section titled “SuperPageDelegate - 页面事件监听”class MyViewController: UIViewController, SuperPageDelegate {
override func viewDidLoad() { super.viewDidLoad()
let pageView = SuperSDKManager.shared.createPageView() pageView.delegate = self view.addSubview(pageView) pageView.frame = view.bounds pageView.load(url: "https://example.com") }
func pageDidStartLoading(_ page: SuperPageView) { // 开始加载 }
func pageDidFinishLoading(_ page: SuperPageView) { // 加载完成 }
func pageDidFailLoading(_ page: SuperPageView, error: Error) { // 加载失败 }
func page(_ page: SuperPageView, didChangeTitle title: String?) { // 标题变化 }
func page(_ page: SuperPageView, didChangeProgress progress: Double) { // 加载进度变化 (0.0 ~ 1.0) }}SFeedback - 用户反馈
Section titled “SFeedback - 用户反馈”SDK 内置的用户反馈提交,与 H5 的 SuperSDK.submitFeedback 同一条链路:POST /superapi/v2/feedback → 控制台「业务运营 → 用户反馈」按项目 × 环境查看、搜索并标记处理状态。SDK 自动补齐 spid / env / device_id / platform / app_version / sdk_version / os_version / device_model,服务端记录提交时间与用户 IP;宿主只需提供业务字段。
let request = FeedbackRequest( scene: "settings", title: "打开设置页闪退", content: "进入设置页后约 1 秒必现闪退", subScene: "about", // 可选 userId: currentUserId, // 可选:业务用户 ID,SDK 不维护用户身份 extra: ["page": "settings"] // 可选:附加信息(≤4KB))SFeedback.submit(request) { result in switch result { case .success(let feedbackId): print("feedback stored: \(feedbackId)") case .failure(let error): // error.code: INVALID_ARGUMENT(本地校验失败,未发请求)/ NETWORK_ERROR / RATE_LIMITED / // UNAVAILABLE / PROTOCOL_MISMATCH,或服务端业务 code(INVALID_REQUEST / NOT_FOUND …) print(error.code, error.message) }}| 字段 | 必填 | 限制 |
|---|---|---|
| scene | ✓ | ≤64 字符 |
| title | ✓ | ≤200 字符 |
| content | ✓ | ≤5000 字符 |
| subScene | ≤64 字符 | |
| userId | ≤128 字符 | |
| extra | JSON object,序列化后 ≤4KB |
回调恒在主线程;所有字符串会被 trim,长度按字符数计(服务端为权威)。限流:每 IP 10 次/分钟、每项目 600 次/分钟。提交不是幂等的,SDK 不自动重试。
NativeBlockProvider - 原生组件嵌入
Section titled “NativeBlockProvider - 原生组件嵌入”允许 H5 页面嵌入宿主 App 提供的原生视图(如广告、视频播放器等)。
class MyNativeBlockProvider: NativeBlockProvider {
var supportedBlockTypes: [String] { return ["ad-banner", "video-player"] }
func createBlockView(type: String, params: [String: Any]) -> UIView? { switch type { case "ad-banner": let adView = UIView() adView.backgroundColor = .systemBlue return adView case "video-player": let player = UIView() // 配置视频播放器... return player default: return nil } }
func onBlockShow(blockId: String, view: UIView, type: String) { // Block 进入可视区域 }
func onBlockHide(blockId: String, view: UIView, type: String) { // Block 离开可视区域 }
func onBlockDetached(blockId: String, view: UIView, type: String) { // Block 被移除,释放资源 }}OfflineController - 离线包管理
Section titled “OfflineController - 离线包管理”通过 SuperSDKManager.shared.getOfflineController() 获取。
let offlineController = SuperSDKManager.shared.getOfflineController()
// 查询所有离线包状态let packages = offlineController.getAllPackages()
// 查询指定离线包let state = offlineController.getPackage(host: "example.com")
// 根据 URL 查询对应的离线包let state2 = offlineController.getPackageForUrl("https://example.com/page")离线包远程更新
Section titled “离线包远程更新”SDK 支持从远程站点自动获取并安装最新离线包,无需宿主额外接入代码即可生效。
自动更新行为:
- 探测时机:打开任意 http(s) 页面时,SDK 在页面加载过程中后台静默探测该 host 站点根路径下的
super_meta.json(站点侧发布规范见OFFLINE_PKG_SPEC.md),不阻塞页面渲染,站点未接入(404)视为正常状态 - 生效时机:探测到新版本并下载安装成功后,下次加载该 host 页面时生效,不会刷新当前已打开的页面
- 大小上限:自动模式下单包 50MB 以内才会自动下载,超过则跳过(仅显式调用可下载)
- 探测频控:同一 host 最小探测间隔 30 分钟,避免频繁开关页对站点造成请求压力
显式触发更新:宿主可主动调用 preloadPackage(host:listener:) / preloadAllPackages(listener:) 立即检查更新,绕过频控与大小上限:
class MyUpdateListener: OfflineUpdateListener { func onProgress(host: String, progress: Int) { // 下载进度 0-100 }
func onComplete(result: OfflineUpdateResult) { if result.isSuccess { // 更新成功,下次加载该 host 页面生效 } }}
// 立即检查并更新指定 host 的离线包(绕过频控与 50MB 上限)offlineController.preloadPackage(host: "example.com", listener: MyUpdateListener())
// 立即检查并更新全部已装离线包offlineController.preloadAllPackages(listener: MyUpdateListener())首次调用时若本地尚未安装该 host 的离线包,只要远程清单探测成功,同样会走首装流程(首装同样在下次加载时生效,不影响本次页面渲染)。
站点侧要求:站点需在根路径发布符合 super_meta.json v1 规范的清单文件,并保证声明的 pkg_path 与站点同源。完整字段定义、zip 打包工具链约束(zip -r deflate,不支持流式 data-descriptor 产物)见 OFFLINE_PKG_SPEC.md。
离线页运行时约定(自 1.0.0.59 起)
Section titled “离线页运行时约定(自 1.0.0.59 起)”离线命中时,SDK 通过自定义 scheme super-offline://{host}/… 请求级拦截整个离线包(对齐 Android,支持 base:'/' 绝对路径与 History 路由)。离线页在 iOS 上的 origin 因此是 super-offline://{host} 而非真实域名,接入方(尤其 H5 侧)需注意:
- 非 secure context:离线页不满足安全上下文,
Service Worker、crypto.subtle等受安全上下文限制的 API 不可用。若离线包依赖这些能力,请勿以离线包形态分发。 - API 跨域:离线页打自家后端为跨域请求,后端需返回 CORS 头;带 cookie 凭据时不能用
Access-Control-Allow-Origin: *,需回显具体 origin 并加Access-Control-Allow-Credentials: true。 - POST body:经
fetch/XHR发往super-offline://同源路径的POST/PUT请求体会被 WebKit 丢弃;API 请求一律走绝对 https URL。 - 页内资源引用用相对路径或
base:'/'绝对路径均可(都会命中本地包);跨域绝对 https URL 资源不经离线拦截,照常走网络。
ShareController - 短链生成
Section titled “ShareController - 短链生成”通过 SuperSDKManager.shared.getShareController() 获取,提供短链生成能力(与 Android SuperSDK.getShareController() 对齐)。
let shareController = SuperSDKManager.shared.getShareController()
// 生成短链shareController.requestShortUrl(url: "https://example.com/very/long/path?a=1") { code, msg, shortUrl in if code == "SUCCESS", let shortUrl = shortUrl { print("短链: \(shortUrl)") }}
// 通过 HTML 内容生成短链(访问短链时直接渲染 HTML,不做 302 跳转)shareController.requestShortUrlWithHtml(html: "<html>...</html>") { code, msg, shortUrl in // ...}
// 两个方法均支持自定义短链前缀shareController.requestShortUrl(url: "https://example.com/page", baseUrl: "https://s.a.com/") { code, msg, shortUrl in // ...}回调 code 取值:SUCCESS 成功(shortUrl 为短链字符串)、BAD_REQUEST 参数为空、FAIL_API 服务端返回错误(msg 为错误信息)、FAIL_PARSE 响应解析失败、FAIL_REQUEST 网络请求失败。
H5 侧对应能力为
SuperSDK.requestShortUrl()/requestShortUrlWithHtml();系统分享面板由 JSBridgeshare方法内置提供(UIActivityViewController),无需宿主注入。
Service 协议说明
Section titled “Service 协议说明”HostConfigService - 宿主配置
Section titled “HostConfigService - 宿主配置”提供宿主 App 的基本配置信息。
class MyHostConfigService: HostConfigService { var appChannel: String { "AppStore" } var appVersionCode: Int { 1 } var appVersionName: String { "1.0.0" } var sdkApiBaseUrl: String? { nil } // 自定义 API 地址,nil 使用默认
func generateDeviceId() -> String? { nil } // 宿主接管 deviceId 生成,nil 使用 SDK 默认逻辑}| 成员 | 类型 | 说明 |
|---|---|---|
appChannel | String | 渠道标识(如 AppStore) |
netEnv | ApiEnv | ⚠️ 已废弃(SDK 从未消费);项目环境请使用 setAPIEnvironment(_:) |
appVersionCode | Int | 版本号 |
appVersionName | String | 版本名称 |
sdkApiBaseUrl | String? | 自定义 API 地址 |
generateDeviceId() | String? | 宿主接管 deviceId 生成(可选,默认 nil) |
generateDeviceId - 宿主接管 deviceId 生成(可选):
- 仅在 SDK 需要生成新 deviceId 时调用(首次安装,Keychain 无既有值),已持久化的 deviceId 继续沿用,不受影响(缓存优先)。
- 返回非空字符串:SDK 采用该值作为 deviceId 并写入 Keychain;返回
nil/空串:走 SDK 默认生成逻辑(identifierForVendor → UUID 兜底)。 - 实现要求:同步快速返回,且多次调用应返回稳定值。
EventService - 事件上报
Section titled “EventService - 事件上报”接收 SDK 产生的事件,对接宿主的埋点平台。
class MyEventService: EventService { func onEvent(_ event: Event) { // 上报到自己的埋点平台 Analytics.track(event.eventName, params: event.params) }}Event 属性:
| 属性 | 类型 | 说明 |
|---|---|---|
eventName | String | 事件名称 |
eventType | Int | 事件类型 |
timestamp | Int64 | 时间戳 |
params | [String: Any] | 事件参数 |
LoginService - 登录服务
Section titled “LoginService - 登录服务”当 H5 需要登录时,SDK 调用此服务。
class MyLoginService: LoginService { func requestLogin(from viewController: UIViewController, callback: @escaping (_ code: String, _ msg: String, _ loginInfo: HostLoginInfo?) -> Void) { // 拉起宿主的登录流程 LoginManager.shared.login(from: viewController) { result in if result.isSuccess { let loginInfo = HostLoginInfo( userId: result.userId, token: result.token, extra: nil ) callback("SUCCESS", "登录成功", loginInfo) } else { callback("FAIL", "登录失败", nil) } } }}HostLoginInfo:
| 属性 | 类型 | 说明 |
|---|---|---|
userId | String | 用户 ID |
token | String | 登录 Token |
extra | [String: Any]? | 扩展信息(可选) |
HostMethodService - 宿主自定义方法
Section titled “HostMethodService - 宿主自定义方法”允许 H5 调用宿主自定义方法,实现业务扩展。
class MyHostMethodService: HostMethodService { func invokeAsync(methodName: String, params: [String: Any]?, callback: @escaping (_ code: String?, _ errMsg: String?, _ result: [String: Any]?) -> Void) { switch methodName { case "getUserInfo": callback("SUCCESS", nil, ["name": "张三"]) default: callback("NOT_FOUND", "方法不存在", nil) } }}NavigationService - 接管 openPage(URL 路由)
Section titled “NavigationService - 接管 openPage(URL 路由)”宿主实现此协议即可接管 openPage:拿到 URL + 配置,自行决定如何打开(自有原生页 / 重定向 / 自有 WebView 等)。返回 true 表示已自行处理;返回 false 交回 SDK 默认容器打开(选择性拦截 + SDK 兜底)。
class MyNavigationService: NavigationService { func openPage(url: String, config: PageConfig) -> Bool { // 命中宿主路由 → 打开自己的原生页,返回 true 表示已接管 if let vc = MyRouter.matchNative(url) { MyRouter.push(vc) return true } // 其余交回 SDK 默认容器打开 return false }}若你想用 SDK 的 WebView 容器但自己控制展示,在
openPage里自取容器即可,无需走 SDK 默认页:let v = SuperSDKManager.shared.getPageController().createPageView()v.load(url: url)// v.onClosePageListener = { ... } 可响应 H5 的 closePage// 把 v 放进你自己的 VC 展示,然后 return true
PageConfig:
| 属性 | 类型 | 说明 |
|---|---|---|
showTitleBar | Bool | 是否显示标题栏 |
showBackButton | Bool | 是否显示返回按钮 |
initialTitle | String | 初始标题 |
容器行为 ·
target="_blank"/window.open:H5 中<a target="_blank">链接点击与window.open(url)会被容器自动识别,统一通过openPage在端上以新页打开(等价于appbridge.openPage),并走上面的NavigationService。H5 无需额外适配;与 Android 行为一致。
SuperPageView - 页面视图方法
Section titled “SuperPageView - 页面视图方法”SuperPageView 提供以下方法供宿主调用:
| 方法 | 说明 |
|---|---|
load(url: String) | 加载 URL |
reload() | 重新加载 |
canGoBack() -> Bool | 是否可以后退 |
goBack() | 后退一页 |
handleBackPressed(exitAction: @escaping () -> Void) | 处理返回键,优先级:前端拦截 > 页面历史回退 > exitAction |
setSafeArea(statusBarHeight: Int, navigationBarHeight: Int) | 设置安全区域(物理像素) |
setImmersiveBottom(_ immersive: Bool) | 底部是否沉浸(默认 true=内容延伸到底部安全区下,现有行为)。置 false(浏览器场景):WebView 内容缩短到底部安全区之上 + 页面 env(safe-area-inset-bottom)=0 + UA SafeAreaBottom=0,第三方站点底栏紧贴系统栏、无多余白边。仅作用底部(顶部恒沉浸);应在注入安全区/首次 load 前调用 |
sendBroadcast(eventKey: String, jsonData: String?) | 向当前 WebView 发送广播 |
onShow() | 通知页面进入前台 |
onHide() | 通知页面进入后台 |
onDestroy() | 销毁页面 |
HostNetworkExtensionService - 网络请求扩展(可选)
Section titled “HostNetworkExtensionService - 网络请求扩展(可选)”允许宿主为 SDK 内部网络请求(settings / 事件上报 / 归因 / 短链等)追加 query 参数与 request header。协议方法全部有默认实现,不实现即不生效,既有接入方无需改动。
class MyProvider: NSObject, SuperSDKProvider { private let networkExtension = MyNetworkExtension()
func getHostNetworkExtensionService() -> HostNetworkExtensionService? { return networkExtension }}
class MyNetworkExtension: HostNetworkExtensionService { func getExtraQueryParams(_ context: SuperRequestContext) -> [String: String]? { // 开启响应混淆:SDK 自身不会默认追加该参数 return ["suenc": "1"] }
func getExtraHeaders(_ context: SuperRequestContext) -> [String: String]? { return ["X-Host-Trace": traceId()] }}SuperRequestContext 提供 url / urlString / path / host / method,宿主可据此按请求条件化返回。
合并规则(SDK 侧强制,宿主无法绕过):
- SDK 自有 query / header 恒胜——query 名精确匹配,header 名大小写不敏感匹配。例如 SDK 已设
X-Super-API-ENV,宿主返回x-super-api-env也不会覆盖它Authorization、Cookie等认证凭据 header 不接受本接口注入- 非法项被单项跳过,其余照常生效;日志只记 key 与拒绝原因,不记 value
- 实现抛出的异常一律被捕获,不阻断 SDK 主流程
- 每次请求实时读取,SDK 不缓存返回值
- 方法在发起请求的线程上同步调用,实现必须快速返回、不得阻塞
响应混淆(suenc)
Section titled “响应混淆(suenc)”服务端在请求带 ?suenc=1 时会用自定义 Base64 表编码 JSON 响应体并回 X-Su-Enc: b64t1。SDK 内部请求会自动解码(含非 2xx 的错误响应),宿主无需介入——只要按上文注入 suenc=1 即可。
⚠️ 只用于降低通用关键字扫描的有效性,不是加密:不提供机密性、防篡改、防重放。
若宿主自己发起了 suenc 请求,可调用 SDK 的解码能力:
// 查询本端支持的 codec,决定是否发送 suenc=1let capabilities = SuperSDKManager.shared.getSuEncCapabilities()// ["supported": true, "codecs": ["b64t1"]]
// codec 必须直接使用响应 X-Su-Enc header 的原始值,不接受自定义编码表do { let json = try SuperSDKManager.shared.decodeSuEnc(encodedBody, codec: codec)} catch let error as SuEncError { // .unsupportedCodec / .decodeFailed / .invalidUTF8}注意事项:
- 解码失败一律视为请求失败,绝不回落读取明文——那正是该协议要防的降级
- 若请求带了
suenc=1却收到无X-Su-Enc的响应,SDK 判定该线路失败并自动切换下一个 baseUrl- 编码表在 SDK 发布后永不变更;新表一定使用新的 codec key,因此
codec必须取自响应 header 而非硬编码
Service 总览
Section titled “Service 总览”| Service | 说明 | 必要性 |
|---|---|---|
HostConfigService | 宿主配置(渠道、版本、环境等) | 推荐实现 |
EventService | 事件上报回调 | 可选 |
LoginService | 登录服务 | 可选 |
HostMethodService | 宿主自定义方法调用 | 可选 |
NavigationService | 自定义导航服务 | 可选 |
NativeBlockProvider | Native Block 创建和生命周期 | 可选 |
HostNetworkExtensionService | SDK 内部请求的 query / header 扩展 | 可选 |
JSBridge
Section titled “JSBridge”前端通过 window.appbridge 调用原生能力,与 Android 保持一致。详见 JSSDK 文档。
// 获取环境信息const env = await appbridge.getEnvAsync();
// 打开页面appbridge.openPage('https://example.com', { title: '标题' });
// 调用宿主方法const result = await appbridge.callHostMethod('methodName', { key: 'value' });完整接入示例
Section titled “完整接入示例”// 1. AppDelegate 初始化@mainclass AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { try! SuperSDKManager.shared.initialize( spid: "ab12cd34", provider: MySDKProvider() ) return true }}
// 2. Provider 实现class MySDKProvider: SuperSDKProvider { private let hostConfig = MyHostConfigService()
func getHostConfigService() -> HostConfigService? { hostConfig } func getLoginService() -> LoginService? { nil } func getEventService() -> EventService? { nil } func getHostMethodService() -> HostMethodService? { nil } func getNavigationService() -> NavigationService? { nil } func getNativeBlockService() -> NativeBlockProvider? { nil }}
class MyHostConfigService: HostConfigService { var appChannel: String { "AppStore" } var appVersionCode: Int { 1 } var appVersionName: String { "1.0.0" } var sdkApiBaseUrl: String? { nil } // func generateDeviceId() -> String? { MyDeviceIdManager.deviceId } // 可选:宿主接管 deviceId 生成}
// 3. 使用 ViewController 方式打开页面class HomeViewController: UIViewController { func openWebPage() { let vc = SuperSDKManager.shared.createPageViewController(url: "https://example.com") navigationController?.pushViewController(vc, animated: true) }}
// 4. 使用 PageView 方式嵌入class EmbedViewController: UIViewController, SuperPageDelegate { private var pageView: SuperPageView?
override func viewDidLoad() { super.viewDidLoad()
let pv = SuperSDKManager.shared.createPageView() pv.delegate = self view.addSubview(pv) pv.frame = view.bounds pv.autoresizingMask = [.flexibleWidth, .flexibleHeight] pv.load(url: "https://example.com") self.pageView = pv }
func pageDidFinishLoading(_ page: SuperPageView) { print("页面加载完成") }
func page(_ page: SuperPageView, didChangeTitle title: String?) { self.title = title }}- 初始化时机:必须在使用任何 SDK 功能前调用
SuperSDKManager.shared.initialize() - 线程安全:UI 操作在主线程执行,JSBridge 回调已自动切换到主线程
- 内存管理:WKScriptMessageHandler 的循环引用已在 SDK 内部处理
- ATS:如需访问 HTTP 地址,需在 Info.plist 中配置 App Transport Security
- 离线包:SDK 内置离线包支持,加载 URL 时会自动匹配本地资源
- 麦克风:宿主 Info.plist 必填
NSMicrophoneUsageDescription;不要替换 SDK 的uiDelegate