Skip to main content

Python Mobile App Development: Bringing PySide6 on iOS

Comments

Python mobile app development reaches iOS in Qt 6.12. PySide6 developers can ship native iOS apps from the same codebase they already use for Android and desktop, with no Swift or Objective-C rewrite and no second codebase to keep in sync.

Since Qt 6.5 brought PySide6 applications to Android, a natural question has been: what about Python on iOS? iOS presents a fundamentally different challenge than Android, but with Qt 6.12, Python developers can ship to iPhone and iPad without leaving the PySide6 ecosystem for another Python-to-iOS toolchain.

Can you Build iOS Apps with Python?

Yes 🎉. As of Qt 6.12, PySide6 applications can run natively on iOS. Cross-compiling PySide6 for iOS produces a set of static .a libraries. Those static libraries are linked directly into the app's Xcode project alongside Qt's own static frameworks and BeeWare’s Python.xcframework (until Python 3.15 is released, which will provide official iOS support), so everything ends up in one final app binary instead of being loaded dynamically at runtime.

Why Does iOS Need a Different Approach than Android?

iOS requires Qt to be statically linked into the application binary. Qt ships as static libraries for iOS rather than shared dylibs. If PySide6 modules were loaded as dynamic files, Qt's symbols would appear twice, and this would cause duplicate symbol errors at load time.

The solution is to statically link every PySide6 module into the binary and pre-register them with the Python interpreter before Py_Initialize.

How Does Qt Take Over the iOS app Lifecycle?

iOS applications are driven by UIApplicationMain, which takes over the process and never returns. Qt's iOS platform plugin provides qt_main_wrapper, which calls UIApplicationMain with Qt's own application delegate, making the full Qt platform integration available, including signals, slots, and the event loop. We set Xcode's LD_ENTRY_POINT build setting, so Qt owns the process from the start.

Qt's run-loop-integration then hands control back to our main(), which initializes Python and runs the application script.

How do I run a PySide6 app on iPhone or iPad?

Getting a PySide6 app running on iOS takes three steps: cross-compile PySide6 once per Qt version, describe your app in a config file, then generate and build the Xcode project.

Step 1 - Cross-compile PySide6:

python pyside-setup/tools/cross_compile_ios/main.py build --qt-install-path ~/Qt/6.12.0

This downloads a Python.xcframework, generates a CMake toolchain file, and cross-compiles shiboken6 and PySide6 for ios_arm64, producing static libraries.

This step only needs to run once per Qt version. The output can be reused across all your iOS applications.

Step 2 - Describe your app:

A pyside6-ios.toml file is required for Xcode project generation. It contains the information needed to configure the Xcode project. Currently this needs to be written manually; work is ongoing to support auto-generation from the existing PySide6 project.

[app]
name = "My PySide6 App"
bundle-id = "com.example.mypyside6app"
output-dir = "generated"

[pyside6]
modules = ["QtCore", "QtGui", "QtWidgets"]

[python]
version = "3.14"
scripts = ["scripts/main.py"]

[signing]
style = "Automatic"

Step 3 - Generate and build the Xcode project:

python pyside-setup/tools/cross_compile_ios/main.py generate -c pyside6-ios.toml

open generated/MyPySide6App.xcodeproj

This generates:

  • main.mm: Initializes Python, registers all PySide6 modules as built-ins, runs the Python script

  • Info.plist: iOS app metadata

  • project.pbxproj: links all Qt frameworks, PySide6 static archives, Python.xcframework, and iOS system frameworks; sets LD_ENTRY_POINT

From Xcode, select your device and press Run ▶️.

pyside-ios

Figure 1: Xcode Project (Left), Device screenshot (Right)

One Codebase for Android and iOS

With PySide6 now targeting both Android (since Qt 6.5) and iOS (since Qt 6.12), the same PySide6 codebase can target both major mobile platforms. The build and packaging steps differ under the hood, static linking on iOS versus dynamic loading on Android, but your application code doesn’t need to change between them. A single PySide6 project, deployable to desktop, Android, and iOS without a rewrite.

PySide6 on iOS: Current Limitations

Considering this is the first version that will include iOS deployment support, we have identified a few limitations that you need to be aware of. If you believe you can contribute a fix of any of the following items, we will be happy to review them:

  • No third-party packages yet. Packages with C extensions (numpy, Pillow, etc.) cannot be used; no iOS wheels exist on PyPI.
  • No iOS Simulator support yet. Testing currently requires a physical device; simulator support is ongoing research.
  • Manual Xcode project generation. A pyside6-ios-deploy console script (parallel to pyside6-android-deploy) is planned to replace the manual generate-and-open Xcode project step.
  • Currently relies on BeeWare's Python.xcframework. Once Python 3.15 officially is released, we plan to switch to Python's official iOS support.

FAQs

Can you make iOS apps with Python?

Yes. Using PySide6 and Qt 6.12 or later, you can statically compile a Python application into a native iOS app binary and run it on iPhone or iPad. It requires cross-compiling PySide6 for ios_arm64 and generating an Xcode project, but the application code itself is standard PySide6.

Are there other ways to develop iOS apps with Python besides PySide6?

Other Python-to-iOS toolchains exist (for example, BeeWare's Briefcase, which PySide6's iOS tooling reuses Python.xcframework from), as well as kivy-ios package, but PySide6 is the option that gives you the full native Qt widget and QML toolkit.

Does Python support cross-platform mobile development?

Yes, with PySide6 you can now target both Android and iOS from the same PySide6 codebase. The underlying build process differs by platform (Android uses dynamic library loading; iOS requires static linking), but application logic and UI code can be shared across both.

What are the current limitations of Python on iOS?

The main gaps today are third-party packages with C extensions (no iOS wheels exist yet on PyPI), no iOS Simulator support, and manual Xcode project generation rather than a single deploy command. All three are active areas of work.

Do I need to know Swift or Objective-C to ship a PySide6 app to iOS?

No. The generated Xcode project handles the native iOS entry point and app lifecycle for you (main.mm, Info.plist, LD_ENTRY_POINT). Your application logic stays in PySide6; you only need Xcode to build and sign the app, not to write native code.

Where can I Find PySide6 to Test it Out?

The tooling lives in pyside-setup/tools/cross_compile_ios/.

For the full API reference beyond what's covered here, see the official Qt for Python documentation. If you want to see how this same PySide6 approach already works on Android, check out Qt for Python on Android: cross-compiling with pyside6-android-deploy for the parallel workflow.

Feedback, bug reports, and questions are welcome on the Qt bug tracker under the PySide component.

Thank you to Patrick Stinson, who did the initial exploratory work on getting PySide6 running on iOS. Our approach here ended up different from his, but that early groundwork helped get this effort started.

 

Comments

Subscribe to our blog

Try Qt 6.11 Now!

Download the latest release here: www.qt.io/download

Qt 6.11 is now available, with new features and improvements for application developers and device creators.

We're Hiring

Check out all our open positions here and follow us on Instagram to see what it's like to be #QtPeople.