平台给"已适配"发身份证:兼容性声明怎么写才不透支信任

一、这条新闻里能拿走的东西,是那句”不只是能运行”
10 月 22 日苹果发博文,宣布将在 App Store 引入”Made for iPhone Duo”标志,用来标识已经适配其首款折叠机型的应用和游戏;据公开报道,这个标识在 10 月 23 日、也就是 iPhone Duo 在部分地区开售当天出现在相关应用的产品页面上。苹果对它的说明里有一句值得单独摘出来(同样据公开报道):拿到标识代表的不只是”能在大屏上运行”,还包括把内外双屏、更大的显示区域和折叠形态真正用起来。
我们要讨论的就是这半句区分。它把三件平时被混着说的事摆开了:
- 能运行:进程不崩、页面出得来、用到的能力没有被裁掉。绝大多数应用在新硬件上架第一天就满足这一条,所以它不需要声明。
- 布局正确:展开、合起、半折叠三种尺寸下不裁切、不重叠、不误触,可读性达到基线。这一层要改样式和布局判定,工作量可以估。
- 交互充分利用:新形态换来的是并行视野和姿态分工,界面用它承载了什么语义。分屏导航、上半屏预览下半屏控制这类才属于第 3 层,多数应用从来没走到这里。
一个布尔标签必然把三层压成一件,这是声明机制的固有失真,不是谁执行得不认真。拆开看有四条:层次失真——标签不说明它落在第几层;时间失真——验证针对某个版本的某些行为,标签却不记版本、不记验证日期,第二次迭代后没人重跑,声明还在;范围失真——产品页只有一个标志,用户会读成”这台机器上哪儿都适配了”,但适配永远是局部命题,清单页过了不代表某个二级流程的长表单测过;不可证伪——没有撤回与记录机制时,”已经适配”和”曾经适配”在外部看起来一模一样。
所以在我们眼里,一条能被当作证据的兼容声明必须带三件东西:声明者是谁、断言范围具体到哪个功能哪一版、有效期到什么时候。缺任何一件,标签就从工程证据退化成营销位。标志的价值也是真的:它把已经做完的验证变成用户可检索的信号,替用户省掉”到底有没有人试过”那次搜索。失真的补法在声明方自己手里,平台不会替你把层次和范围写出来。
二、适配工作真正分几层:改什么、回归到哪、谁签字
断点、宽高比、安全区那一层的技术清单,站内《手机屏幕回到多形态时代:适配要重算的不只是断点》已经写过一遍,这里不重开那张表。要问的是另一个问题:每一层的完成度由谁签字,签完之后回归范围是什么。因为打标真正消耗的是这两样东西,而不是代码行数。
| 层级 | 需要改什么 | 回归测试范围 | 谁签字 |
|---|---|---|---|
| 尺寸与布局分支 | 不假设固定比例,按容器而不是机型分支 | 全部页面的极值尺寸截图比对 | 前端负责人 |
| 运行时尺寸切换 | 折叠与展开、内外屏切换时场景不重建、状态自持 | 表单、播放、长列表三条关键流程的状态断言 | 客户端与测试共同 |
| 半折叠姿态分工 | 上下屏的角色分配是新设计,不是把同一套控件重排 | 悬停态交互走查、误触与遮挡 | 产品与设计 |
| 摄像头与传感器 | 内外摄切换、取景预览的坐标换算 | 取景与扫码全流程,含旋转与遮挡 | 客户端 |
| 内容重排策略 | 哪些区域该并排、哪些该隐藏 | 同一份数据在不同栏位下不丢信息 | 产品负责人 |
最后一行是唯一能被用户直接感知的判断,也是最容易被跳过的一行。高德公开的适配方案是分屏导航:左侧车道级导航、右侧常规地图的前方路线与路况,两种视野并排,并支持随内外屏切换。它不是”把一屏切成两半”——车道级指引和路况概览分属两个抽象层级,并置之后各承担不同时长的决策,秒级的变道判断与分钟级的路线判断互不打扰。被适配的是这套分工,切屏时要保住的也是这套分工。反面做法我们见得多:列表左右各铺一遍、字号缩到塞得下,第 3 层什么都没做,对外一样说”已适配折叠屏”。
第 2 行和第 3 行的区别也要说清:改样式是编译期的事,改姿态分工是产品规则的事。半折叠时上屏放预览、下屏放控制条,这条规则一旦写进交互就得有”合起之后控制条去哪”的配套答案,否则会出现控制条悬在半屏之外这种谁都没设计过的状态——它不靠加断点解决,只能靠把规则写全。
三、”切屏不丢状态”是验收点,不是特性
据公开报道,苹果在开发工具侧补了折叠形态的模拟器和尺寸变化相关的回调,让应用能在展开、半折叠和内外屏切换时自行调整布局。工具解决的是”能测”,不解决”测什么”。而这一层最常见的故障原因只有一个:尺寸变化被当成一次冷启动。生命周期里视图控制器或活动被整个拆掉重搭,样式跟着重建走一遍,看起来正常,代价是网络请求重发、视频从起点播、表单清空、滚动位置归零。用户感知到的是”我的东西没了”,而且恰好发生在他填到一半的时候。
下面是我们会直接抄进测试计划的用例写法。核心要求是断言落在数据上,不是落在截图上。
- 锚点断言。进入目标页面,向一个输入框写入可辨识的值(形如
probe-<时间戳>),把列表滚到中部并记录偏移。执行折叠↔展开十次,每次回到同一页面断言三件事:页面标识未变、输入值未丢、滚动偏移在约定误差内。任何一次断到空值即整条用例失败,不接受”偶尔能过”。 - 飞行中切屏。在弱网模拟下把带宽压到最低档,发起一次分页加载,请求未完成时切屏。断言请求没有被重发(看抓包条数与请求序号),返回后结果落在原位而不是回到顶部。这条最狠,因为场景重建的副作用最先体现在重发上,而重发在有副作用的接口上等于重复提交。
- 播放与录制。进度非零时切屏,断言时间轴继续;录音或录屏进行中也各跑一次。这两条链路的失败代价是素材丢失,事后无法重试,所以优先级高于所有界面问题。
- 四段姿态往返。展开→半折叠→合起→展开连走一遍,断言上下屏角色分配回到原状、没有残留控件,半折叠引入的分界线在合起后完全消失。
- 弹窗与键盘叠加。对话框打开且软键盘弹出时切屏,断言两者状态不互吞。这一格最容易造出”提交按钮点不到”的不可用状态。
- 时长与泄漏。上述用例连续执行二十分钟,同时看内存与句柄曲线。切屏路径上的泄漏表现为阶梯式上涨,头两次切换看不出来。
这六条里前两条我们当成底线:任何声称”随内外屏切换不丢状态”的功能,至少要能交出这两条的执行记录,否则这句话在我们的文档里只能写成”切屏后布局自适应”——那是一件弱得多的事,也是第 1 层能承诺的上限。
四、打了标之后:承诺的撤回成本比晚打高
标签一旦出现,用户就会把它当承诺读,”没打标”和”体验差”两件事都会被归责到开发者头上。这是声明机制的必然代价,不是平台刁难。我们的立场只有一句:宁可晚打,不虚标。落到操作上四条:
- 打标范围等于已验证范围,不扩写。做不到整站覆盖就在文档里写明”清单与详情已验证、某二级流程未验证”,而不是打一个总标签赌用户不走到那一页。
- 打标自带内部快照。当时打包的版本、跑过的用例编号、失败项与降级说明留一份档。外部看到的是一个标志,被追问时我们要拿得出当时究竟测到哪一层。
- 负向清单排在正向清单之前。把不支持的具体项逐条列出来,这条与站内一贯的做法相同——“能做什么”的清单客户会当成参考,”不做什么”的清单才会被当成依据。
- 虚标的回撤成本远高于晚打。撤下一个标志在外部通常会被读成出过事故,而晚打的成本只是这段时间里没有差异。所以只要第 3 层还没做完,就不要用第 1 层的完成度去声明第 3 层的结论。
第二点在洹拓科技的方案评审里是硬性材料:任何”已支持”三个字进对外文档之前,必须能指出它对应哪条用例的哪一次执行记录。指不出就改写成”该场景未测试”或者”仅验证到某种尺寸”。这条规矩看起来啰嗦,实际省下的是事后自证的成本。
五、搬回自研产品:把”支持”写成三态矩阵
多数自研 Web 与 SaaS 产品没有应用商店那样的标志位可拿,但要回答的却是同一个问题——客户采购表里的”支不支持”。我们的做法是把它做成文档里的一张矩阵,而不是文档末尾一句”适配主流设备”。行是形态,列是关键功能,单元格只用三个状态词:已验证、布局可用、未测试。
| 形态与功能 | 登录鉴权 | 主查询 | 长表单填报 | 文件上传 | 在线预览 |
|---|---|---|---|---|---|
| 直板窄屏 | 已验证 | 已验证 | 已验证 | 已验证 | 布局可用 |
| 折叠展开态 | 已验证 | 已验证 | 未测试 | 布局可用 | 未测试 |
| 半折叠悬停 | 未测试 | 未测试 | 未测试 | 未测试 | 未测试 |
| 平板横屏 | 已验证 | 已验证 | 布局可用 | 已验证 | 已验证 |
| 桌面窄窗分屏 | 已验证 | 布局可用 | 未测试 | 未测试 | 未测试 |
三个状态词的口径必须写在表格上方,否则这张表照样会被读错:
- 已验证:第三节那套状态断言用例跑过,有留档,含失败项记录;
- 布局可用:不裁切、可滚动、能提交,但没有做状态自持验证,切屏或改窗口后不保证输入不丢;
- 未测试:既不是支持也不是不支持,是没有证据。
第三个词最要紧。把”未测试”写成”不支持”是过度自谦,会让自己少卖一块能力;写成”支持”就是虚标,出事时要连别人一起赔。把这两类冲动都用一个中立词挡住,是我们认为三态比二态好用的唯一理由:二态矩阵逼着填表的人猜,三态矩阵允许他承认没做。矩阵之外还要配一行口径说明——覆盖的浏览器主版本区间、最小逻辑宽度、系统字号档位,以及这张表的复核周期;复核周期一到就得重跑,否则它又会退化成第二节里那个”曾经适配”。
六、判断
这件事值得搬进我们日常交付的部分,不是”苹果发了个标志”,而是它把一个一直含糊的说法拆成了三层,并让开发者为声明负责。对用户,标签机制省掉一次搜索;对开发者,它把承诺从上线后挪到了打标前。所以我们签字的写法是三态矩阵加带版本与日期的验证留档,二态(能用、不能用)不是——二态矩阵里的每一个”能用”,都会在半年后变成一次没有记录的争论。
反过来,什么条件下这套做法不成立:如果团队连第三节前两条用例都维护不了——没有弱网模拟、没有可断言的页面标识、切屏后拿不回输入值——那三态矩阵只会填成一堆”未测试”,看起来诚实但给不出任何决策信息。这种时候正确的动作不是降级回二态,而是先把切屏用例的两条底线建起来;一条状态断言用例的成本,比一次”你们不是说不支持吗”的返工便宜得多。形态碎片化这件事不会自己收敛,能收敛的只有我们描述它的方式。