Apps rejected by macOS App Store due to "use of non-public or deprecated APIs"
- Dominant language
- Python
- Stars
- 3.3k
- Forks
- 549
- Avg merge
- 1d 4h
- Merged PRs (30d)
- 40
Description
### Describe the bug
If you use Briefcase package an app for distribution in the macOS App Store, the app will be rejected with the following message:
> **Guideline 2.5.1 - Performance - Software Requirements**
>
> Your app uses or references the following non-public or deprecated APIs:
>
> Contents/Frameworks/Python.framework/Versions/3.12/lib/libtk8.6.dylib
>
> Symbols:
>
> • _NSWindowDidOrderOnScreenNotification
>
> The use of non-public or deprecated APIs is not permitted on the App Store, as they can lead to a poor user experience should these APIs change and are otherwise not supported on Apple platforms.
### Steps to reproduce
1. Generate a Hello World app
2. Sign the app with a macOS App Store distribution certificate
3. Submit the app for publication in the App Store
4. See error described above
### Expected behavior
It should be possible to distribute a macOS app in the App Store.
### Screenshots
_No response_
### Environment
- Operating System: macOS (all)
- Python version: all
- Software versions:
- Briefcase: 0.3.20+
### Logs
_No response_
### Additional context
This is caused by a [known issue with Tk](https://core.tcl-lang.org/tk/tktview/a9969f7ffd966229c4e6).
It has been reported to Python (see python/cpython#129247) - however, there's nothing Python can do to fix this issue.
If your app uses Tkinter, you are unfortunately out of luck. With the current state of Tk, it is not possible to distribute a Tk app in the macOS App Store. You will need to use other distribution mechanisms.
However, if your app does *not* use Tkinter, you can use the Briefcase `cleanup_paths` option to purge the Tkinter libraries as part of the app packaging process. If you add the following to your the macOS section of your pyproject.toml:
```
cleanup_paths = [
"**/Frameworks/Python.framework/**/lib/Tk.*",
"**/Frameworks/Python.framework/**/lib/itcl*",
"**/Frameworks/Python.framework/**/lib/libtcl*",
"**/Frameworks/Python.framework/**/lib/libtk*",
"**/Frameworks/Python.framework/**/lib/tcl*",
"**/Frameworks/Python.framework/**/lib/tdbc*",
"**/Frameworks/Python.framework/**/lib/tk*",
"**/Frameworks/Python.framework/**/lib/thread*",
]
```
the tk binaries will be deleted, which should allow your app to be released. This has the added benefit of reducing the size of your app binary.
---
At the very least, this issue should be documented as a macOS platform quirk (with the fix described above).
It may also be worth formalizing this fix by providing customizable options for what parts of the standard library are installed. Tkinter is only needed by apps that actually use tkinter; for all other apps, it's dead weight in the app bundle. The same goes for curses, maybe sqlite and openssl, and some parts of the non-binary standard library (e.g., the `test` module is almost 31MB, but most apps won't need any of it). Having an analog of "extras" (i.e `pip install foo[extra1,extra2]`), but for the Python standard library, would provide a way to formalize what is removed.
Ideally, this "extras" philosophy would be pushed completely upstream, so that there's a "minimal" standard library, and tkinter is a binary wheel on PyPI... but that's a much bigger argument to be had.
Contributor guide
Research direction
Start with the macOS section of pyproject.toml and the listed cleanup_paths workaround, then review how Briefcase packages the Python framework for App Store distribution. Done means documenting the Tk API rejection and workaround, or defining and validating a supported way to omit unused standard-library components.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- desktop
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100