前两篇文章,一篇写怎么先稳住原功能,一篇写哪些代码该放进 SDK、哪些该留在 App。
这一篇写一个很容易踩坑的问题:SDK接入项目后,项目扫脸核心功能能够正常运行以后,主工程里原来的扫脸代码到底怎么删除。
SDK 接进项目以后,最容易冒出来的想法是:
既然扫脸能力已经放进 SDK 了,那主工程里的旧代码是不是可以大面积删掉?
这件事不能这么做,扫脸这种功能不是一个独立函数,它从相机、人脸识别、测量判断、红绿蓝信号、最终结果,到结果页、历史记录、PDF、弹窗、首页卡片,牵涉的地方很多。
有些代码确实已经没有用了,有些代码只是从"自己实现"变成了"调用 SDK"。
还有些代码看起来也在扫脸功能代码的目录里,但其实服务的是当前 App 的页面、历史和展示规则。
所以这次清理旧代码时,我的判断很简单:每删一块,都先确认这块功能已经由 SDK 负责,并且主工程里没有页面或业务还在依赖它。
一、删除旧代码前,先确认它还在不在用户流程里
删除旧代码时,最容易出错的地方,是它看起来像"没人用了",但实际上还被某个页面绕着用。
所以我没有直接看目录下有哪些文件,而是先考虑几个更具体的问题:
- 用户从扫脸入口进来,还会不会走到这段代码?
- 扫脸页能不能不用它就完成测量?
- 结果页、历史记录、PDF、弹窗还会不会读它的结果?
- SDK 里有没有已经准备好的替代入口?
- 删掉以后,能不能用真机重新走完整个扫脸过程?
这几个问题要全部考虑清楚,才能开始进行删除。
这也是为了保证扫脸核心功能不受影响,因为这类实时功能一旦误删,问题不一定马上出现在编译阶段,可能是到了真机上才表现为:扫脸页卡住、倒计时不走、结果页没有数据、历史记录异常。
所以我把旧代码分成了三类:
- 已经确认不用的,删除。
- 已经改成调用 SDK 的,保留一层薄薄的中间代码。
- 属于 App 页面和历史规则的,继续留在主工程。
后面所有代码删除操作,都是按这个顺序做的。
二、第一批删除的是旧算法对比工具
第一批我选择删除旧算法对比工具,它离用户操作最远,也最容易确认已经不在正式测量里。
做 SDK 的过程中,主工程里曾经留过一套旧算法,用来和 SDK 算出来的结果做对比。
它的作用很明确:确认 SDK 算出来的结果没有明显偏离原项目。
但是,当正式扫脸结果已经改成由 SDK 来算以后,这套对比工具就不应该继续留在项目里,因为它已经不服务用户流程了。
这一轮清理时,我先确认正式结果已经走 SDK,再删除了这类内容:
- 调试入口里的旧算法对比按钮。
- 用来做 SDK 和旧算法对比的工具文件。
- 主工程里只给对比工具使用的旧估算代码。
- 旧的健康指标计算、疾病风险计算、血糖估算、信号处理和波形特征提取代码。
这轮要分清一件事:我删掉的是已经被 SDK 替代的旧对照代码,不是用户正在用的扫脸计算。
这两件事必须分清楚,如果正式结果还没有走 SDK,这些文件当然不能删除,但是,正式结果已经走 SDK 以后,继续留着这套旧算法,反而会让项目后期变得难以维护。后面排查问题时,很容易分不清到底是哪套代码在计算扫脸结果。
三、红绿蓝信号相关代码,不能一口气删除
扫脸结果不是凭空算出来的。
测量过程中,代码要从额头、脸颊这些区域里取颜色变化,再整理成红绿蓝三路信号,页面上还会显示实时波形和实时BPM,如图所示:

这部分一开始也在主工程里,但它不能像旧算法对比工具那样直接删。
原因是:扫脸页还在用这些数据刷新页面,最终结果也需要这些信号继续往下算。
所以这块的做法是分两步。
第一步,先把负责处理信号的代码放进 SDK:
- 红绿蓝信号缓存。
- 波形处理。
- 实时心率估算。
- 测量过程里的临时结果。
第二步,再回到主工程,把重复的数据结构删掉。
这里不是"SDK 有了,所以 App 全删掉"。
更准确的说法是:SDK 负责处理信号,App 继续负责页面显示。
所以主工程里有些文件会留下来,但它们的职责变了:
- 原来它们自己处理信号。
- 现在它们只是把页面需要的数据从 SDK 拿出来。
- 页面不需要知道 SDK 内部怎么处理红绿蓝信号。
这一轮清理完成后,主工程少了一批重复的信号数据结构,但扫脸页的实时波形、实时心率、最终结果生成都没有改变,这种删法比一口气删除干净慢一些,但风险小很多。
四、总分计算是先让 SDK 提供入口,再删除旧文件
健康总分这块,也不能直接删除旧文件,因为结果页会显示总分,PDF 里会用总分,历史记录里也会保存总分。
所以这里的顺序是:
- SDK 先提供一个总分计算入口。
- 主工程把总分计算改成调用 SDK。
- 确认结果页总分、8 项健康指标、3 项疾病风险、PDF、心脏年龄页面都正常。
- 再删除主工程里旧的总分计算文件。
代码层面,主工程最后只需要把参与评分的字段整理给 SDK:
swift
FaceScanHealthScoreRequest(
heartRate: heartRate,
respiratoryRate: respiratoryRate,
hrv: hrv,
systolicBP: systolicBP,
diastolicBP: diastolicBP,
stressIndex: stressIndex,
cardiacLoad: cardiacLoad,
bmi: bmi,
signalQuality: signalQuality,
userAge: userAge
)
这段代码的意思很清楚:总分怎么算,交给 SDK;结果页怎么展示,仍然留在 App。
等主工程已经不再使用旧的总分计算文件以后,再删 HealthScoreCalculator 和配置文件,才是安全的。
如果顺序反过来,先删文件再找谁报错,就会变成被编译错误推着走,这在项目里风险太高了。
因为编译错误只能告诉你"哪里缺东西",不能告诉你"这块业务现在应该归谁负责"。
五、质量判断也只删除实现,不大改扫脸页
扫脸页里有一类判断很关键:人脸太近、太远、晃动、偏头、遮挡、脸部区域是否可用。
这些判断如果出问题,用户可能连正式测量都进不去,所以质量判断这块,我没有为了删代码去重写扫脸页。
更稳的做法是:
- SDK 负责距离、晃动、遮挡、脸部区域是否可用这些判断。
- 主工程保留原来的调用入口。
- 扫脸页继续按以前的方式拿判断结果。
- 原来主工程里的距离、晃动、区域面积等判断逻辑删掉。
也就是说,从扫脸页看,调用方式尽量不变,但里面已经不再自己算,而是把人脸数据整理给 SDK,再把 SDK 的结果整理回页面能用的格式。
代码大概是这个样子:
swift
final class SC_FaceScanQualityEvaluator {
private let sdkEvaluator = FaceScanQualityEvaluator()
func evaluate(faceMesh: SC_FaceMeshResult) -> SC_FaceScanQualitySnapshot {
sdkEvaluator
.evaluate(faceMesh: faceMesh.toSDKFaceMeshResult())
.toAppQualitySnapshot()
}
}
这段代码能说明为什么这一层还要留在主工程:扫脸页继续调用原来的类型,但距离、晃动、遮挡这些判断已经交给 SDK。
这样做的好处是,用户实际操作不会因为清理旧代码而受到影响。
如果为了删除旧质量判断,顺手把扫脸页也重写一遍,那问题就会变复杂,后面如果提示不准、倒计时不走、正式测量进不去,很难判断是 SDK 判断有问题,还是页面改动引入了新问题。
这就是我一直控制清理范围的原因:只删除旧的代码实现,不要顺手修改页面和业务功能逻辑。
六、有些代码看起来旧,但不能删除
清理到后面,最容易犯的错误是:看到主工程里还有扫脸相关文件,就觉得它们都应该继续删除。
但第二篇文章里已经讲过,扫脸 SDK 不是把整个扫脸功能代码目录搬走。
主工程里仍然需要保留这些东西:
- 结果页需要的数据结构。
- 历史记录的存取。
- 用户资料读取。
- 首页卡片展示。
- PDF 和弹窗文案。
- 健康指标的正常、偏高、偏低判断。
- 写入历史前压住结果波动的处理。
- 一小段把 App 数据整理成 SDK 请求的中间代码。
这些不是"旧算法残留"。
它们服务的是当前 App 的页面和业务规则,如果把它们也删掉,SDK 可能看起来更彻底,但 App 会失去自己的产品表达方式。结果页怎么展示、PDF 怎么写、历史记录怎么存,这些都不应该交给 SDK 统一决定。
所以这轮清理更合理的目标是:主工程里不再保留重复算法,但继续保留当前 App 必须负责的页面、历史和展示规则。
七、每删一块代码,都要回到真机确认一次
旧代码清理不能只看搜索结果。
搜索能告诉你某个类名有没有引用,编译能告诉你有没有语法和类型错误,但它们都不能证明用户实际扫脸功能正常。
所以每一轮清理后,我都回到同一套检查:
- 项目代码能不能编译通过。
- 扫脸页能不能正常开始测量。
- 无人脸、太近、太远、晃动、遮挡提示是否正常。
- 能不能进入倒计时。
- 能不能进入正式测量。
- 最后能不能出结果。
- 结果页总分是否正常。
- 8 项健康指标是否正常。
- 3 项疾病风险是否正常。
- PDF、健康指标弹窗、疾病风险弹窗、心脏年龄页面是否正常。
这组检查解决的是一个很实际的问题:代码删掉以后,用户体验有没有受影响。
只要这个问题验证通过了,旧代码删除的任务才算完成。
八、这次留下来的经验
扫脸 SDK 做到后半段,我不再把重点放在"主工程还能删掉多少文件"。
我只看一个问题:删除这段代码之后,用户扫脸核心功能会不会受影响?
如果它原来做的事情已经由SDK负责,比如结果计算、健康总分计算、质量判断等,那主工程里的旧代码实现就可以删除。
如果它还影响结果页、历史记录、PDF、弹窗、首页卡片、写入本地扫脸结果历史记录之前的结果波动处理等,就先留在app里。
代码删除到这里就可以停了,不需要为了少几个代码文件继续往下删。