那会儿我正给客户做一款健身打卡H5封装APP,用的是他们自己注册的苹果开发者账号,证书类型选了In-House,但没料到他们那个账号去年被封过一次,重新激活时勾选了“自动管理设备”,结果系统偷偷把200多台测试机全踢出了UDID列表。掉签不是偶然,是整整齐齐、像秋天落叶一样,一片接一片地掉。

第一次发现是在周三下午,客户发来截图:三台iOS 17.5的iPhone 14 Pro,同一秒闪退。我立刻登后台查签名日志——证书还在有效期,描述文件也没过期,可设备列表里,那三台的UDID后面赫然标着“Revoked”。我翻聊天记录才想起来,客户上周让助理用新Apple ID重装了TestFlight,顺手点了“同步所有设备”,而那个Apple ID绑定的iCloud账户,恰好在苹果风控系统里标记为“高风险共享行为”。苹果不告诉你为什么,但它认得出来:同一个家庭组下,6个不同手机号注册的Apple ID,反复在3台Mac上切换登录、导出IPA、重签名……它不封你账号,只悄悄把你设备列表里的ID一个个灰掉。

价格?真没法说死。上个月找的渠道A,打包+超级签名+7天掉签包换,一口价1890,含30台设备;前天换了个新渠道B,说是用企业级证书+双层描述文件兜底,结果首批发12台,3台当天掉,补签三次后对方甩来一句:“你客户设备里装了‘爱思助手’,我们证书和它的签名冲突。”收了我2360,还附赠一句“建议卸载第三方工具”。最离谱的是上周五,一个朋友介绍的个人开发者,他用自己的苹果开发者账号跑内测,收费按月算——880/月,不限设备数,但必须用他指定的Apple ID登录,且每台设备每月要手动点一次“信任开发者”。我试了两台,一台点完信任,隔天开App直接黑屏;另一台更绝,点完信任后,系统弹窗提示:“此Apple ID未启用双重认证,无法完成签名验证”。原来他账号开了双重认证,但设备端没同步开启——苹果签名这玩意儿,证书、设备、Apple ID、系统版本、甚至iCloud密钥链状态,得凑齐七颗龙珠才能亮一次。

技术原理?别听那些公众号讲“就是换个证书”。真实情况是:你上传IPA,签名服务先解包,删掉原始签名目录,再注入新的entitlements(权限清单),填入你的Bundle ID、Team ID、Provisioning Profile路径,最后用私钥(.p12文件)对整个包重签名。但关键不在“签”,而在“验”——每次App启动,iOS会实时校验:这个签名对应的证书是否在设备信任列表里?证书是否被吊销?描述文件是否匹配当前设备UDID?如果客户用的是个人苹果开发者账号,那他的证书只能绑100台设备,且每台必须手动在设置→通用→设备管理里点信任;如果是企业账号,理论上无限设备,但苹果会盯你分发行为——比如单日下载超500次、IP地址跳变频繁、或同一证书在非企业官网域名下分发……它不声不响就把证书废了。

稳定性?我拿自己主力机(iPhone 15 Pro,iOS 17.4.1)跑了三个月对比:用客户自己的苹果开发者账号走Ad Hoc分发,平均掉签周期是11.3天;换用某家所谓“永久签名”的超级签名服务,实际撑了19天,第20天早上打开直接白屏,后台显示证书已吊销;最稳的一次,是借了合作律所的苹果开发者账号(他们有D-U-N-S编号+企业资质),用In-House证书+自建MDM服务器托管描述文件,连续87天零掉签——但他们拒绝对外提供服务,理由是“怕连累主账号”。

遇到过最荒诞的问题,是客户把APP上架苹果商城失败后,回头让我用超级签名临时救场,结果签名后的IPA在iPhone上能装能开,但在iPad上点图标就转圈。查日志才发现,客户原H5页面用了WebGL渲染运动轨迹图,而签名时没勾选“允许WebGL加速”entitlement,iOS默认禁用——这玩意儿不报错,也不提示,就静静卡死。后来加了一行代码重新签名,花了47分钟,客户在微信里发了个“OK”加三个句号。

现在我桌上贴着张便签:“别信‘永久’,信‘下次掉签时间’”。
上一批客户用的签名服务,掉签通知是自动发邮件的,时间精确到秒——2024年6月12日14:22:08,第1台掉;14:22:11,第2台;14:22:15,第3台……像定时炸弹倒计时。我盯着屏幕,手心出汗,不是因为损失钱,而是那一刻突然意识到:我们写的不是App,是寄生在苹果生态缝隙里的临时签证。它有效,但永远悬着;它可用,但不敢托付核心功能;它解决了上架前的燃眉之急,却把长期信任,悄悄押给了下一次掉签前的30分钟。

不过说实话,上周六晚上,我用自己刚续费的苹果开发者账号,给老家表弟的小程序做了个IPA签名,他装上后兴奋地发来视频:老人用语音指令打开记账本,全程没点一次屏幕。那一刻,签名掉不掉,好像也没那么重要了。

——毕竟,有人等不及苹果商城上架的90天审核,有人只想要一个能打开的图标。
而我的工作,就是让那个图标,在它该亮的时候,真的亮起来。