首页 > 解决方案 > 如何从 python 访问自定义 swift 或 Objective C 框架

问题描述

大多数示例展示了从 swift/objective-c 代码调用 python 框架。但我想做相反的事情,我想从 python 调用 swift 的公开函数。有没有办法做到这一点?

将用 Objective-C/swift 编写的自定义、特定于应用程序的非系统框架(即不在随提供的框架包装器之一中PyObjC)类公开到 PyObjC 桥上的 python 的最佳方法是什么。

我想开发一个“混合”应用程序,其中应用程序的某些部分在 Objective-C/swift 中,而其他部分在 python 中,两侧通过 PyObjC 桥集成。

我能找到的大多数文档似乎都集中在目标是让所有特定于应用程序的代码都在 python 中,并让 python 通过桥和 pre 调用 AppKit 类等的情况-打包的系统框架包装器。

标签: pythonobjective-cswiftpyobjc

解决方案


PyObjC 的主要用例是从 Python 访问 Objective-C 代码,但也可以使用 PyObjC 在 Python 中为 ObjC/Swift 应用程序实现一些功能。

不过,这充其量几乎没有记录。有两种方法可以解决这个问题:

  1. 实现对插件包的支持并使用 python 代码创建插件包(使用 py2app 打包)。这记录在一个非常古老的 PyObjC 教程中:https ://pyobjc.readthedocs.io/en/latest/tutorials/embedded.html

  2. 向应用程序添加对 Python 扩展的显式支持。

我会选择第二个选项,因为这最终是更容易实现的选项。

要到达那里,您需要做很多事情:

  1. 初始化 python 解释器并运行一些启动代码。请参阅“Py_Initialize()”和“PyRun_SimpleString()”以继续此操作(或有关在应用程序中嵌入 Python 的教程)。

    确保在运行启动代码后释放 GIL(这在嵌入时一般不需要,但在使用 PyObjC 时需要,尤其是在不同线程可能调用 Python 代码时)

  2. 向 Python 公开 ObjC API

    这可能容易或困难,取决于两个部分之间的接口有多复杂。向 Python 公开 ObjC 类很容易:只需使用“objc.lookUpClass(classname)”来访问 Python 中的 ObjC 类。这也会自动公开类上的任何方法。

    方法访问可能需要更多工作,特别是当方法具有传递引用参数或使用块时。

    访问全局变量和 C 函数是可能的,但也需要更多的工作,因为 PyObjC 无法从 ObjC 运行时 API 读取它们。PyObjC 文档包含有关如何在需要时访问它们的信息。

  3. 在代码的 Python 和 ObjC 部分之间建立链接。我会在 Python 中创建 Python 对象,然后添加 ObjC API(使用 PyObjC)以将它们传递给应用程序的 ObjC 代码。

    为了在 ObjC 方面获得更好的体验,您需要在 ObjC 中定义将由 Python 代码实现的协议。

最后一点:所有这些都是为了从 Python 而不是 Swift 访问 Objective-C API。这也应该适用于 Swift 代码,但前提是您在 swift (@objc) 中实现 ObjC 接口。PyObjC 不能用于访问任意 swift API。


推荐阅读