The easist way to use these packages is by creating a project with Briefcase <https://github.com/beeware/briefcase>
__. Briefcase will download pre-compiled
versions of these support packages, and add them to an Xcode project (or
pre-build stub application, in the case of macOS).
NOTE Briefcase usage is the officially supported approach for using this support package. If you are experiencing diffculties, one approach for debugging is to generate a "Hello World" project with Briefcase, and compare the project that Briefcase has generated with your own project.
The Python support package can be manually added to any Xcode project; however, you'll need to perform some steps manually (essentially reproducing what Briefcase is doing). The steps required are documented in the CPython usage guides:
For tvOS and watchOS, you should be able to broadly follow the instructions in the iOS guide.
There are 2 ways to access the Python runtime in your project code.
You can use the Python Embedded C API to instantiate a Python interpreter. This is the approach taken by Briefcase; you may find the bootstrap mainline code generated by Briefcase a helpful guide to what is needed to start an interpreter and run Python code.
An alternate approach is to use PythonKit. PythonKit is a package that provides a Swift API to running Python code.
To use PythonKit in your project:
-
Add PythonKit to your project using the Swift Package manager. See the PythonKit documentation for details.
-
Create a file called
module.modulemap
insidePython.xcframework/macos-arm64_x86_64/Headers/
, containing the following code:
module Python {
umbrella header "Python.h"
export *
link "Python"
}
- In your Swift code, initialize the Python runtime. This should generally be done as early as possible in the application's lifecycle, but definitely needs to be done before you invoke Python code:
import Python
guard let stdLibPath = Bundle.main.path(forResource: "python-stdlib", ofType: nil) else { return }
guard let libDynloadPath = Bundle.main.path(forResource: "python-stdlib/lib-dynload", ofType: nil) else { return }
setenv("PYTHONHOME", stdLibPath, 1)
setenv("PYTHONPATH", "\(stdLibPath):\(libDynloadPath)", 1)
Py_Initialize()
// we now have a Python interpreter ready to be used
- Invoke Python code in your app. For example:
import PythonKit
let sys = Python.import("sys")
print("Python Version: \(sys.version_info.major).\(sys.version_info.minor)")
print("Python Encoding: \(sys.getdefaultencoding().upper())")
print("Python Path: \(sys.path)")
_ = Python.import("math") // verifies `lib-dynload` is found and signed successfully
To integrate 3rd party python code and dependencies, you will need to make sure
PYTHONPATH
contains their paths; once this has been done, you can run
Python.import("<lib name>")
. to import that module from inside swift.