只因升级一下编程语言的版本,就导致开发的应用被拒、审核不通过、上架不了应用商店,这种鲜少发生的事情如今正在一些 Python 开发者身上上演。
近日,据外媒 LWN 报道,一些开发者在将他们的应用程序中使用的 Python 版本从 3.11 升级到 3.12 版本后,重新提交到苹果 App Store 时,遭到了苹果审核团队的拒绝。
这也引起了许多开发者的关注。那么,问题究竟出在 Python 3.12 还是苹果审核团队?
一个字符串导致 App 审核失败
回看事情经过,起因是一位名为 Eric Froemling 的开发者在 GitHub Python 仓库的 issue 中分享了他的遭遇,其表示:
“这并不是一个传统意义上的 bug,但我最近经历了一场磨难。我的应用在苹果的 App Store(具体是 Mac App Store)上更新之后,因为我将使用的 Python 版本从 3.11 更新到 3.12,导致更新被拒绝了。”
起初,Eric Froemling 也并不明白此前可以正常上架的应用程序,为什么做了一下迭代后就不可以了。与此同时,App Store 审核团队在拒绝 Eric Froemling 的 App 时也没有直接说明原因,只冰冷地回复一句「我们无法为您提供更多信息」。
几经折腾,Eric Froemling 终于忍无可忍,向苹果团队提交了一份申诉邮件,苹果这才给他一定的提示:
根据指南 2.5.2 条 ——性能——软件要求
应用程序安装或启动了可执行代码。具体来说,该应用程序使用 itms-services URL 方案安装应用程序。
稍作解释,itms-services URL 方案是苹果公司提供的一种用于分发和安装 iOS 应用程序的方式,通常用于分发不在 App Store 上发布的应用,如企业内部应用或测试版应用。它允许用户通过点击一个链接直接在他们的 iOS 设备上安装应用程序,而无需通过 App Store。
以下是一个基本的 itms-services URL 结构:
itms-services://?action=download-manifest&url=https://example.com/manifest.plist
其中:
itms-services://:这是 URL 方案,用于告诉 iOS 设备这是一个应用安装请求。
?action=download-manifest:指定要执行的操作,这里是下载应用的清单文件。
经过大量的排查,Eric Froemling 发现违规文件是 Lib/urllib/parse.py(Python 标准库的 Urllib 解析器)及其关联的 .pyc。在 Python 3.12 代码中,似乎添加了一个“itms-services”字符串,而苹果 App Store 似乎正在扫描这个字符串,并自动拒绝包含它的任何内容(Eric Froemling 称至少在他的案例中是这样)。
最终,Eric Froemling 从他的 Python 代码中删除该字符串后,更新后的 App 终于通过了审核,成功上架 App Store。
引发争议的苹果审核及反馈规则
令 Eric Froemling 郁闷的其实并非是“itms-services”字符串埋下的“坑”,而是苹果 App Store 的审核规则。
他表示,“当苹果公司最终告诉我,Lib/urllib/parse.py 及其关联的 .pyc 是有问题的文件时,此时追踪到底发生了什么并不难。现在回想起来,我感到很沮丧,我没有想到早点通过 Python 本身对 itms-services 进行全文搜索,也没有偶然发现其他人遇到这种情况。”
众所周知,相比写代码,Debug 才是让很多开发者头疼的问题,正因此,也才有了前几日我们报道过的“调查 7 年的 Bug 时,花费了三个月时间来排查,最终只修改了一行代码”事件的发生。
时下,Eric Froemling 耗费了大量的精力进行 Debug,只删除了一个字符串就解决问题,在不少开发者看来,「其实本可以通过苹果透明的审核机制来避免的,然而现实就是,苹果的审核机制不透明」。
CPython 核心开发者:App Store 审核规则既偏执又难以捉摸!
对此,CPython 核心开发者 Russell Keith-Magee 在看到 Eric Froemling 提交的 issue 后,随即发布了一篇《处理与 App Store 审核流程不兼容的问题》文章,把这个事情单独拧出来说了一遍。
Russell Keith-Magee 称,这个问题也为 CPython 核心开发团队提出了一个有趣的哲学问题:我们愿意为适应 App Store 审核流程付出多大努力?
Russell Keith-Magee 解释称,之所以发生这种情况,问题在于苹果公司的 macOS App Store 会自动拒绝任何包含 itms-services 字符串的应用程序。苹果的 macOS 商店分发的软件是经过沙盒处理的,经过沙盒处理的应用程序禁止使用带有 itms-services 方案的 URL。
苹果的自动审查程序会捕捉到 urllib 解析器中处理这些 URL 的代码,即使相关应用程序从未使用过 itms-services:// URL 也是如此。标准库中就有这样的代码,因此应用程序会被拒。
「对字符串进行一些轻度混淆似乎可以避免这一问题。不过,这并不能保证永远都能解决这个问题,而且可能会引发混乱,也不能保证这将是我们需要解决的唯一一个应用程序验证问题」,Russell Keith-Magee 说,「虽然现在引发问题的是一个 macOS 应用,但类似的 App Store 自动审核流程也存在于 iOS、Android 和微软平台应用商店中。苹果的审核无疑是其中最......偏执和高深莫测的......,它们的验证和验收流程完全不透明」。
回归问题本身,这次导致 App 审核不通过的原因是 Python 3.12 中包含了“itms-services”字符串,作为官方如何解决这一问题,Russell Keith-Magee 给出了两个建议:
新增编程语言设计的目标:将“符合应用程序商店要求”作为 CPython 的设计目标,并整合任何必要的补丁来满足这一要求。这意味着用户不需要进行任何特殊的补丁处理来使 CPython“兼容应用商店”;但这也意味着有时会合并一些丑陋的混淆代码。如果某个时点规则发生变化,可能需要更多的补丁;而如果某个旧规则被移除,我们将没有明确的信号来表明某个特定的混淆代码不再需要。
把这个视为一个分发问题。开发时,使用 CPython 就正常用,只不过后面要使用生成打包应用程序的工具(如 Briefcase、Py2app、Buildozer 等)负责对 CPython 进行补丁,使其符合应用商店的要求。就 Briefcase 和 Bulldozer 而言,这些工具还会修补和构建自定义 CPython 库。从过往历史上看,这是因为 CPython 并不支持 iOS 和 Android;Python 3.13 版本源码现在无需打补丁即可运行......但如果我们将此视为分发问题,那么打补丁将成为一项持续性要求。
不过,这两种方式也可能会导致两个新问题的出现,Russell Keith-Magee表示:
(1) 的方式这也意味着分发的 Python 并不是“官方”的 Python,因为它们已经被修改以供分发;我不知道我们应该如何考虑这是否存在安全或品牌风险。我猜,Linux 发行版在发布 Python 时打的补丁与此类似,也许这并不是一个问题。
对于(2),还有一个额外的问题,即 CPython 是否应该记录它所知道的 App Store 审核的各种限制。
因此,CPython 应该如何处理这种混淆?
对此,另一位 CPython 核心开发者 Alex Gaynor 提出了第三种方案:
灵感来源于我们在 pyca/cryptography 上的经验启发。我们经常收到错误报告,说“你拒绝解析这张证书,虽然它在技术上是无效的,但它是由[某个广泛使用的设备或 CA]签发的”。我们得出的答案是:
一般来说,我们会接受能解决这类问题的 PR,前提是这些 PR 要小,要本地化,而且一般不会太糟糕。但是,在我们合并 PR 之前,需要有人向第三方投诉(如苹果 App Store),并确保他们意识到了这个问题,并表示他们会采取一些措施来解决这个问题。我们接受的任何解决方法都会有一定的时间限制(即我们会在几个版本中删除解决方法)。
这样既能让用户获得良好的 OOTB 体验,又不会让大公司简单地将其怪异问题外部化到 OSS 项目中,从而在两者之间保持平衡。
6 月 20 日,Keith-Magee 写道,他想到了另一种方法:与其混淆源代码(苹果可能会认为这是“试图规避合法的安全审查程序”),不如在构建时添加一个选项,删除我们知道有问题的代码。
Mac 文件夹将包含一个 diff,其中描述了需要应用到源代码树中的改动(在本例中,删除了 parse.py 中对 itms-server URL 的支持;但如果需要,也可以扩展)。
configure 将获得一个 --with-app-store-patch 选项。在大多数平台(包括 macOS)上,该选项默认为禁用,但在 iOS 上会启用。如果启用,它将在构建标准库之前应用补丁。该选项也可以接受一个文件(即,--with-app-store-patch=path/to/patch),这样,如果在特定 Python 版本的维护窗口关闭后,App Store 的规则在未来某个时间发生了变化,发行商仍有一个受支持的选项来提供更新的补丁。
是的,这实质上是复制了分销商可以轻易复制的东西,但它的好处是,CPython 作为一个项目,可以提供一个官方列表,列出 App Store 合规性所需的更改。
这听起来更容易让人接受吗?
最后
最终,结果几天内部思考,Keith-Magee 在 6 月 25 日回复道,「感谢大家的意见,我刚刚提交了#120984(https://github.com/python/cpython/pull/120984)来实现该--with-app-store-compliance 选项」,以此解决因字符串导致 App 被 App Store 拒之门外的事情。他在请求中提到,这个选项可以用于 iOS 和 macOS 以外的平台,但目前没有这样的使用案例。如果一切顺利,它将在 Python 3.13 中可用。
令人沮丧的是,不少开发者反馈,像 Python 这样的自由软件项目不得不浪费时间,想方设法绕过不透明的审查程序,以便开发人员能够为非自由平台编写软件。HN 网友评价道:
不只是苹果公司会玩这种把戏。
试试用 PyInstaller 编译 Python 应用程序,同时开启 Windows Defender 实时扫描(默认设置)。如果没有 Defender 的阻止,你甚至无法编译二进制文件。
同样,尝试在打开 Windows Defender 的情况下运行 PyInstaller 生成的二进制文件。Defender 会说这是恶意程序,不会运行它。
两个主要的操作系统平台都不遗余力地阻止你发布和运行 Python 应用程序,这有点反乌托邦。
在这一次经历中,CPython 核心开发者 Keith-Magee 和其他 CPython 开发者还能果断站出来,其所采取的方法似乎是为 Python 应用程序开发者提供最佳体验的最省事的选择。然而,几乎可以肯定,这不会是最后一次有项目遇到这个问题。
来源:
https://lwn.net/SubscriberLink/979671/4fb7c1827536d1ae/
https://discuss.python.org/t/handling-incompatibilities-with-app-store-review-processes/56011/15
https://news.ycombinator.com/item?id=40815130
由 CSDN 和 Boolan 联合主办的「2024 全球软件研发技术大会(SDCon)」将于 7 月 4 -5 日在北京威斯汀酒店举行。
由世界著名软件架构大师、云原生和微服务领域技术先驱 Chris Richardson 和 MIT 计算机与 AI 实验室(CSAIL)副主任,ACM Fellow Daniel Jackson 领衔,华为、BAT、微软、字节跳动、京东等技术专家将齐聚一堂,共同探讨软件开发的最前沿趋势与技术实践。