NEHotspotConfiguration.applyConfiguration 行为与 BSSID 变化说明
1. 背景
本文整理 iOS NEHotspotConfigurationManager.applyConfiguration(_:completionHandler:) 的接口行为、iOS 系统底层 Wi-Fi 加入流程、扫描行为、BSSID 变化风险,以及在 OPPO 互传热点场景中的排查建议。
接口定义:
- (void)applyConfiguration:(NEHotspotConfiguration *)configuration
completionHandler:(void (^ __nullable)(NSError * __nullable error))completionHandler API_AVAILABLE(ios(11.0), watchos(7.0)) API_UNAVAILABLE(macos, tvos);
该接口的核心作用是:App 将一个 Wi-Fi 配置提交给 iOS 系统,由系统尝试加入指定 SSID 的 Wi-Fi 网络。
它不是 Wi-Fi 扫描接口,也不是底层连接控制接口。App 只能提交配置,真正的扫描、匹配、关联、认证、DHCP、网络切换均由 iOS 系统 Wi-Fi 服务处理。
2. applyConfiguration 的主要行为
2.1 配置校验
调用后,iOS 会先校验配置和运行环境,常见校验项包括:
- App 是否具备
Hotspot Configurationentitlement。 - SSID 是否合法。
- 密码是否符合安全类型要求。
- 安全类型是否匹配,例如开放网络、WPA/WPA2/WPA3、EAP 等。
- 当前系统是否允许 App 添加该 Wi-Fi 配置。
- 当前设备 Wi-Fi 是否可用。
- 是否已有 pending 的 Wi-Fi 配置请求。
如果配置不合法,completionHandler 会返回 error。
2.2 系统接管 Wi-Fi 加入流程
配置通过后,iOS 底层通常会进入如下流程:
App 提交 Wi-Fi 配置
↓
iOS Wi-Fi 服务接管
↓
查找目标 SSID
↓
使用已有扫描缓存或触发 Wi-Fi 扫描
↓
选择一个 BSSID
↓
发起 Authentication / Association
↓
完成安全认证或四次握手
↓
DHCP 获取 IP
↓
更新当前网络状态
↓
回调 App
这些步骤均由系统控制,App 无法直接介入。
3. iOS 系统底层扫描行为
调用 applyConfiguration 后,iOS 底层通常会为了加入目标 Wi-Fi 执行扫描或使用已有扫描结果。
可能发生的行为包括:
- 查询系统已有 Wi-Fi 扫描缓存。
- 主动触发 Wi-Fi scan。
- 多信道查找目标 SSID。
- 对隐藏 SSID 发 Probe。
- 目标 SSID 不可见时,短时间等待或重试扫描。
- 根据系统策略停止扫描或放弃连接。
需要明确:
applyConfiguration 不是持续扫描 API。
扫描只是 iOS 为完成加入目标 SSID 而执行的内部动作。
App 不能控制或获取以下信息:
- 扫描频率。
- 扫描持续时间。
- 扫描信道。
- 扫描到的 Wi-Fi 列表。
- 是否命中扫描缓存。
- 具体选择了哪个 BSSID。
- 系统何时停止扫描或放弃连接。
因此,业务逻辑不应依赖该接口实现“持续等待目标热点出现”的能力。系统可能短时间内等待或重试,但不保证无限持续扫描。
4. completionHandler 的语义
completionHandler(error == nil) 不严格等价于已经连上目标 Wi-Fi。
它更接近于:
系统接受了配置,并且加入流程没有立即失败。
因此可能出现以下情况:
apply error == nil
但当前 SSID 不是目标 SSID
或:
apply error == nil
SSID 已切换
但 IP / DHCP / TCP / WebSocket 不可用
互传业务不能只依赖 apply 回调判断 Wi-Fi 已连接成功。
5. 常见错误
常见 NEHotspotConfigurationError 包括:
invalid
invalidSSID
invalidWPAPassphrase
invalidWEPPassphrase
userDenied
pending
systemConfiguration
unknown
含义示例:
userDenied:用户拒绝加入。pending:已有加入请求尚未完成。systemConfiguration:系统配置失败。invalidSSID:SSID 不合法。invalidWPAPassphrase:WPA 密码不合法。invalidWEPPassphrase:WEP 密码不合法。unknown:系统未给出明确原因。
6. joinOnce 行为
如果设置:
configuration.joinOnce = true
表示一次性加入。
特点:
- 系统不会长期保存为稳定自动加入网络。
- App 退后台、锁屏、网络切换后,系统可能断开或不再自动重连。
- 适合临时热点、设备配网、互传热点。
- 不适合长期保持连接的 Wi-Fi。
如果 joinOnce = false,系统可能保存该网络,后续自动加入行为更接近普通 Wi-Fi。
7. BSSID 相关行为
7.1 SSID 与 BSSID
SSID = Wi-Fi 名字
BSSID = 具体 AP 的 MAC 地址
同一个 SSID 可能对应多个 BSSID:
SSID: OPPO-Share
BSSID A: 2.4G AP
BSSID B: 5G AP
BSSID C: 6G AP
NEHotspotConfiguration 通常只指定 SSID,不指定 BSSID。具体连接哪个 BSSID 由 iOS 系统决定。
7.2 BSSID 是否会变化
BSSID 在连接过程中可能变化。
常见场景包括:
- 同 SSID 多 AP 漫游。
- 同一热点存在 2.4G / 5G / 6G 多频 BSSID。
- OPPO 热点重启。
- OPPO 热点切换频段。
- 普通热点切换到高速热点。
- SoftAP 使用随机 MAC 或虚拟 BSSID。
- Wi-Fi 7 / MLO / 多链路场景。
如果是单一 OPPO SoftAP,且热点不重启、不切频,BSSID 通常较稳定。
7.3 BSSID 变化是否会导致连接失败
BSSID 变化有可能导致 Wi-Fi 连接失败,但不是所有 BSSID 变化都会失败。
高风险场景如下:
iOS 扫到 SSID=A, BSSID=1
↓
iOS 准备关联 BSSID=1
↓
OPPO 热点重启或切频
↓
BSSID=1 消失,变成 BSSID=2
↓
iOS 关联旧 BSSID 失败
还可能出现:
apply error == nil
但实际没有连上目标 SSID
或:
SSID 连上了
但 DHCP 未完成
或:
已连上后立即 deauth / disassoc
正常企业 Wi-Fi / Mesh 漫游中,如果 SSID、安全参数、网关、DHCP 环境一致,BSSID 从 A 切到 B 通常不会导致连接失败,最多出现短暂抖动。
8. OPPO 互传热点场景风险
在 iPhone 加入 OPPO 热点的互传流程中,热点生命周期较短,因此 BSSID 变化风险更明显。
典型流程:
OPPO 启动热点
↓
iOS 调 applyConfiguration
↓
OPPO 热点切频 / 重启 / BSSID 变化
↓
iOS 使用旧扫描结果尝试连接
↓
连接失败或超时
典型表现:
apply返回 nil,但 SSID 未切换。- SSID 已切换,但 IP 不对。
- DHCP 未完成。
- WebSocket 连接失败。
- 空口包看到 Association 后 Deauth。
- OPPO 侧显示连接超时或传输超时。
9. 推荐成功判断
不要只判断:
apply error == nil
建议组合判断:
apply error == nil
+
当前 SSID == 目标 SSID
+
本机 IP 已获取
+
对端 IP / 端口可达
+
WebSocket / HTTP 连接成功
BSSID 可以记录并作为辅助判断,但不建议作为唯一成功条件。
10. 排查建议
10.1 App 日志
关注:
applyConfiguration startapply callback- 当前 SSID
- 当前 BSSID
- 本机 IP
smartVerifySSID- WebSocket connect
- HTTP download / upload start
10.2 iOS Wi-Fi / sysdiagnose / IPS
关注:
- Association
- Authentication
- Deauthentication
- Disassociation
- AutoJoin
- DHCP
- BSSID change
- SSID change
NEHotspotwifidairportd
10.3 空口包
关注:
- Probe Request / Probe Response
- Authentication Request / Response
- Association Request / Response
- EAPOL
- Deauthentication
- Disassociation
- DHCP Discover / Offer / Request / Ack
10.4 OPPO 热点日志
关注:
- 热点启动时间。
- 热点 SSID。
- 热点 BSSID。
- 频段。
- 是否重启热点。
- 是否切换高速热点。
- 是否有客户端关联。
- 是否分配 IP。
11. 建议的业务流程
互传场景建议按以下流程处理:
OPPO 热点启动并稳定
↓
OPPO 通过 BLE 下发 SSID / 密码 / IP / port
↓
iOS 调 applyConfiguration
↓
等待 apply 回调
↓
轮询确认当前 SSID
↓
确认本机 IP / 网关 / 对端 IP 可达
↓
WebSocket 连接
↓
进入文件传输
如果失败:
SSID 不正确 → 重新 apply 或回退 BLE/热点流程
SSID 正确但 IP 不正确 → 等待 DHCP 或重试
IP 正确但端口不可达 → 检查 OPPO 服务是否启动
WebSocket 超时 → 检查热点稳定性、BSSID 是否变化、TCP 是否可达
12. 总结
applyConfiguration 是请求 iOS 加入指定 Wi-Fi 的接口,不是扫描接口。调用后,iOS 底层会为了加入目标 SSID 执行扫描、匹配、关联、认证、DHCP 等动作,但这些过程由系统控制,App 不可见也不可控。
BSSID 在连接过程中可能变化。如果 BSSID 变化发生在扫描、关联、认证、DHCP 这些关键窗口期,尤其是 OPPO 热点重启或切频导致旧 BSSID 消失,就可能导致 Wi-Fi 连接失败。
互传业务中,应以 SSID + IP + 对端可达 + WebSocket/HTTP 成功 作为最终成功判断,而不是只依赖 apply 回调或 BSSID。