前言

欢迎加入开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net

iOS 和 macOS 的实现是三个原生平台中最"优雅"的——Apple 提供了 ASWebAuthenticationSession 这个专门为 OAuth 设计的 API,一个方法调用就搞定了浏览器打开和回调接收。不需要配置 Intent Filter,不需要手动处理深度链接。理解这个实现有助于我们看清 OpenHarmony 适配中哪些复杂度是"平台强加的"。

一、ASWebAuthenticationSession 的演进

1.1 历史版本

请添加图片描述

1.2 ASWebAuthenticationSession 的优势

let session = ASWebAuthenticationSession(
    url: authURL,
    callbackURLScheme: scheme
) { callbackURL, error in
    // 认证完成或取消
}
session.prefersEphemeralWebBrowserSession = preferEphemeral
session.presentationContextProvider = self
session.start()

一个 API 完成了 Android 需要 CallbackActivity + Intent Filter + Chrome Custom Tabs 三个组件才能做到的事情。

1.3 与其他平台的对比

维度 iOS/macOS Android OpenHarmony
API 数量 1个 3个组件 2个方法 + 宿主集成
回调方式 闭包回调 Activity 启动 onNewWant 回调
配置负担 AndroidManifest module.json5 + EntryAbility
取消处理 自动(error 参数) 手动(dangling calls) 手动(dangling calls)

二、prefersEphemeralWebBrowserSession

2.1 什么是 Ephemeral Session

session.prefersEphemeralWebBrowserSession = true
preferEphemeral 行为
false(默认) 共享 Safari 的 Cookie 和登录状态
true 使用独立的浏览器会话,不共享 Cookie

2.2 使用场景

场景 推荐值 原因
用户登录 false 利用已有的登录状态,减少输入
切换账号 true 不使用已有的登录状态
隐私敏感 true 不留浏览痕迹

2.3 各平台的 Ephemeral 支持

平台 支持 实现方式
iOS/macOS prefersEphemeralWebBrowserSession
Android FLAG_ACTIVITY_NO_HISTORY
OpenHarmony openLink 不支持
Web window.open 无法控制

📌 OpenHarmony 的 openLink API 目前不支持隐私浏览模式。如果需要这个功能,可能需要使用 Web 组件(ArkWeb)替代 openLink,但这会失去系统浏览器的 Cookie 共享优势。

三、presentationContextProvider 窗口锚定

3.1 iOS 实现

extension FlutterWebAuthPlugin: ASWebAuthenticationPresentationContextProviding {
    func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
        return UIApplication.shared.keyWindow!
    }
}

3.2 macOS 实现

func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
    return NSApplication.shared.keyWindow!
}

3.3 窗口锚定的作用

有锚定 无锚定
认证弹窗出现在当前窗口上方 可能出现在错误的窗口
用户体验一致 多窗口时可能混乱

3.4 OpenHarmony 不需要窗口锚定

OpenHarmony 的 openLink 直接打开系统浏览器应用,不是在当前窗口上方弹出。所以不需要窗口锚定的概念。

四、iOS 与 macOS 实现差异

4.1 代码差异

// iOS
#if os(iOS)
import UIKit
typealias ASPresentationAnchor = UIWindow
#endif

// macOS
#if os(macOS)
import AppKit
typealias ASPresentationAnchor = NSWindow
#endif

4.2 差异对比

维度 iOS macOS
窗口类型 UIWindow NSWindow
获取方式 UIApplication.shared.keyWindow NSApplication.shared.keyWindow
认证弹窗 底部弹出 Sheet 居中弹出窗口
用户交互 触摸 鼠标/键盘

4.3 共享的逻辑

除了窗口类型不同,iOS 和 macOS 的核心逻辑完全相同:

  1. 创建 ASWebAuthenticationSession
  2. 设置 prefersEphemeralWebBrowserSession
  3. 设置 presentationContextProvider
  4. 调用 start()
  5. 在闭包中处理结果

五、取消处理的优雅性

5.1 iOS 的取消处理

let session = ASWebAuthenticationSession(...) { callbackURL, error in
    if let error = error as? ASWebAuthenticationSessionError,
       error.code == .canceledLogin {
        result(FlutterError(code: "CANCELED", message: "User canceled", details: nil))
        return
    }
    if let url = callbackURL {
        result(url.absoluteString)
    }
}

5.2 与 Android/OpenHarmony 的对比

平台 取消检测方式 时机
iOS/macOS ASWebAuthenticationSessionError.canceledLogin 即时
Android App resumed + cleanUpDanglingCalls 延迟(回到前台时)
OpenHarmony App resumed + cleanUpDanglingCalls 延迟(回到前台时)

💡 iOS 的取消检测是即时的——用户点击"取消"按钮的瞬间就能收到回调。Android 和 OpenHarmony 需要等用户切回 App 才能检测到取消。这是 ASWebAuthenticationSession 的一个明显优势。

5.3 对 OpenHarmony 的启示

OpenHarmony 目前没有类似 ASWebAuthenticationSession 的统一 API。如果未来 HarmonyOS 提供了专门的 Web 认证 API,可以像 iOS 一样实现即时取消检测。

六、错误处理

6.1 iOS 端的错误类型

enum ASWebAuthenticationSessionError: Int {
    case canceledLogin = 1
    case presentationContextNotProvided = 2
    case presentationContextInvalid = 3
}
错误 含义 处理
canceledLogin 用户取消 返回 CANCELED 错误
presentationContextNotProvided 没有设置窗口锚定 代码错误,不应发生
presentationContextInvalid 窗口锚定无效 窗口已销毁

6.2 映射到 Dart 层

try {
  final result = await FlutterWebAuth.authenticate(...);
} on PlatformException catch (e) {
  if (e.code == 'CANCELED') {
    // 用户取消了认证
  }
}

所有平台的取消错误都统一为 CANCELED 错误码,Dart 层不需要区分平台。

七、三平台实现总结

7.1 综合对比

维度 iOS/macOS Android OpenHarmony
浏览器方案 ASWebAuthenticationSession Chrome Custom Tabs openLink + startAbility
回调机制 闭包自动回调 CallbackActivity onNewWant
取消检测 即时 延迟 延迟
Ephemeral
配置负担 AndroidManifest module.json5 + EntryAbility
代码复杂度 中高

7.2 OpenHarmony 适配的参考价值

从 iOS 学到的 从 Android 学到的
统一 API 的简洁性 static callbacks 的设计
即时取消检测的理想 dangling calls 清理机制
错误码统一 Intent Filter → skills 映射

总结

本文分析了 iOS/macOS 端的 ASWebAuthenticationSession 实现:

  1. ASWebAuthenticationSession:一个 API 完成浏览器打开和回调接收
  2. prefersEphemeralWebBrowserSession:隐私浏览模式,OpenHarmony 暂不支持
  3. 即时取消检测:iOS 的优势,Android/OpenHarmony 需要延迟检测
  4. 窗口锚定:iOS/macOS 特有,OpenHarmony 不需要
  5. 错误码统一:所有平台的取消都映射为 CANCELED

下一篇我们正式进入 OpenHarmony 适配——从插件工程搭建开始。

如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!


相关资源:

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐