Python Program Banned from Apple App Store Due to a Single String
App Store Rejection: The Hidden String Costing Python Developers
Python developers are facing an unusual problem. Upgrading their programming language version is causing app rejections in the App Store.
Recently, some developers upgraded from Python 3.11 to 3.12. When they resubmitted their apps to Apple's App Store, they were rejected.
This issue has caught many developers' attention. Is the problem with Python 3.12 or Apple's review team?
A String Causes App Review Failure
Eric Froemling, a developer, shared his experience on GitHub. He said:
"This isn't a typical bug. My app update was rejected from the Mac App Store after I updated from Python 3.11 to 3.12."
At first, Eric didn't understand why his previously approved app was now rejected.
The App Store review team didn't explain why. They just said, "We can't provide more information."
After several attempts, Eric sent an appeal to Apple. They finally gave him a hint:
According to guideline 2.5.2 - Performance - Software Requirements:
The app installs or runs executable code. Specifically, it uses the itms-services URL scheme to install apps.
The itms-services URL scheme is Apple's way to distribute iOS apps outside the App Store. It's often used for internal or test apps.
It lets users install apps directly on their iOS devices without using the App Store.
A basic itms-services URL looks like this:
itms-services://?action=download-manifest&url=https://example.com/manifest.plist
After much investigation, Eric found the problem file: Lib/urllib/parse.py (Python's standard library URL parser) and its .pyc file.
In Python 3.12, an "itms-services" string was added. Apple seems to be scanning for this string and automatically rejecting apps that include it.
Finally, Eric removed this string from his Python code. After that, his updated app passed review and was successfully listed on the App Store.
Controversial Apple Review and Feedback Rules
Eric Froemling wasn't upset about the "itms-services" string itself. He was frustrated with Apple's App Store review rules.
He said, "Once Apple told me the problem was in Lib/urllib/parse.py and its .pyc file, it wasn't hard to figure out what happened."
"Looking back, I'm disappointed I didn't search for 'itms-services' in Python earlier. I also didn't find other people with the same issue."
As many know, debugging is often harder than writing code.
Eric spent a lot of time debugging. He only needed to delete one string to fix the problem. Many developers think this could have been avoided if Apple's review process had been clearer. But in reality, Apple's review process isn't transparent.
CPython Core Developer: App Store Review Rules are Strict and Unpredictable!
Russell Keith-Magee, a CPython core developer, wrote an article about this issue. He asked: How much should we change to fit App Store rules?
The problem is that Apple's macOS App Store automatically rejects apps with the "itms-services" string. This is true even if the app never uses itms-services:// URLs.
Russell suggests two solutions:
1. Make "App Store compliance" a goal for CPython. This means users won't need to patch CPython, but it might lead to ugly code.
2. Treat it as a distribution issue. Use tools like Briefcase or Py2app to patch CPython for app stores.
Both options have pros and cons. Option 1 means distributing a modified Python. Option 2 requires ongoing patching.
Alex Gaynor, another core developer, suggested a third option:
Accept small, localized fixes for these issues.
Before merging, someone must complain to a third party (like Apple) about the problem.
Set time limits on these fixes.
This balances user experience with pushing big companies to fix their own issues.
Keith-Magee later suggested a fourth option:
Add a build option to remove problematic code. This would be a cleaner solution than obfuscating code.
This option would:
Include a diff file describing changes.
Add a --with-app-store-patch option to configure.
Allow distributors to provide updated patches if needed.
This lets CPython officially list changes needed for App Store compliance.
Keith-Magee asks if this solution seems more acceptable.
Conclusion
After a few days of thinking, Keith-Magee replied on June 25th. He submitted a pull request (#120984) to add a --with-app-store-compliance option. This should solve the issue of apps being rejected by the App Store due to a string.
He mentioned this option could be used for platforms other than iOS and macOS, but there's no current need.
If all goes well, it will be available in Python 3.13.
Many developers are frustrated that free software projects like Python have to waste time finding ways around unclear review processes. This is just to let developers create software for non-free platforms.
A HN user commented:
It's not just Apple doing this. Try compiling a Python app with PyInstaller while Windows Defender is on. You can't even compile without Defender blocking it.
Also, try running a PyInstaller-made binary with Defender on. The defender will call it malware and won't run it.
It's a bit dystopian that both main OS platforms are trying hard to stop you from releasing and running Python apps.
In this case, Keith-Magee and other CPython developers took quick action. Their solution seems to be the easiest way to give Python app developers the best experience.
However, it's almost certain that this won't be the last time a project faces this issue.