iOS 26 之后,你的 iOS 版本检测代码可能已经不准了
iOS 26发布后,Safari的UA字符串不再更新系统版本,这一旨在保护用户隐私的改变,却让开发者依赖了近二十年的版本判断逻辑彻底失效。
今年初,有人发现 StatCounter 的数据显示 iOS 26 的升级率只有 16%。
这个数字让人困惑。苹果用户向来升级积极,怎么会这么低?
去查了才发现——数据本身就是错的。
问题出在一件很多开发者还不知道的事上。
iOS 26 发布之后,Safari 的 UA 字符串里,系统版本号不再更新了。
你问它”你在什么系统上跑”,它告诉你 18.7。
但实际上它跑在 iOS 26 上。
StatCounter 读取 UA 里的版本号来统计用户系统分布,于是大量 iOS 26 用户被归进了”iOS 18″的桶里。

但事情比这还复杂。
同一台 iPhone,不同浏览器给你的答案完全不一样。
以下是同一台 iPhone 上实测的两条 UA,同样是 iOS 26.5:
// SafariMozilla/5.0 (iPhone; CPU iPhone OS 18_7 like Mac OS X) ... Version/26.5 Mobile/15E148 Safari/604.1// ChromeMozilla/5.0 (iPhone; CPU iPhone OS 26_5_0 like Mac OS X) ... CriOS/149.0.7827.137 Mobile/15E148 Safari/604.1
Safari 告诉你系统是 18.7。
Chrome 告诉你系统是 26.5.0。
同一台手机,差了八个大版本。

为什么会这样?
Safari 是苹果自己的浏览器,它主动选择了冻结版本号——出于隐私保护的考量,不想让网站通过 UA 追踪用户的具体系统版本。
Chrome 是第三方浏览器,没有跟进这个策略,还是老老实实上报真实版本。
大致分两类:
跟 Safari 一样冻结 CPU 字段的——Opera、Edge iOS,以及部分国产浏览器。
直接写真实版本的——Chrome、UC 浏览器。
还有更特别的,百度 iOS 把真实版本藏在了自己的私有字段里,不按任何通用规则来。
所以现在的情况是:同一台 iPhone,不同浏览器,拿到的版本号可能完全不同,需要不同的解析策略。以前一个正则搞定所有情况的时代,过去了。
但 Safari 也没有完全不给你信息。
注意看这行:
Version/26.5
CPU 字段冻结了,但 Version/ 字段还是真实的 Safari 版本号。
而 iOS 26 之后,苹果统一了版本号——Safari 26 对应 iOS 26,Safari 的大版本号就等于 iOS 的大版本号。
所以如果你需要判断用户是不是在 iOS 26 及以上,读 Version/ 字段,比读 CPU iPhone OS 可靠得多。
哪些代码正在悄悄出错?
// ❌ 这个判断在 Safari 上永远拿到 18,不是真实版本const match = ua.match(/OS ([\d_]+) like Mac OS X/)const iosVersion = match?.[1].replace(/_/g, '.')// ❌ 这个判断永远不会执行,因为 Safari 从 18 直接跳到了 26if (iosVersion >= 19) { enableFeature()}
如果你的代码里有类似的版本号判断,在 Safari 用户身上,它已经在返回错误结果了。
用 Chrome 访问的用户不受影响,但 iOS 上 Safari 的流量占比超过 70%,这意味着大多数 iOS 用户都在走这条路径。
还有一件事值得一提。
iOS 上没有 Client Hints。
Android 和 Windows 上,当 UA 不可靠的时候,还可以用 Client Hints API 拿到真实的系统版本。
但 iOS 上的所有浏览器都必须使用苹果的 WebKit 引擎,而 WebKit 不支持 Client Hints。
所以在 iOS 上,你只能靠 UA 字符串本身解决这个问题,没有其他退路。
正确的思路是什么?
判断功能支不支持,用特性检测,不要用版本号。

如果你真的需要知道 iOS 大版本,读 Version/ 字段,不要读 CPU iPhone OS。
但要注意,Version/ 只在 Safari 上等于 iOS 版本,Chrome 和其他浏览器不适用这个规则。
这就是为什么现在的 UA 解析比以前复杂——不同浏览器需要不同的解析策略,没有一个万能的正则能处理所有情况。
把 iOS 26 的 Safari UA 丢进解析工具,结果会告诉你版本是 18.7。

感兴趣可以用自己的浏览器试一下:https://yangtianxia.github.io/ua-browser/playground
这不是工具的问题,它如实读出了 UA 里的内容。
真正的变化是:以前 UA 里的版本号是事实,现在它只是一个参考——而且不同浏览器的参考价值还不一样。
这不是一个能等着别人帮你解决的问题。如果你的代码依赖 iOS 版本号做判断,现在就是检查它的时候了。
夜雨聆风