如何从python访问自定义Swift或Objective C框架

时间:2018-09-26 09:40:00

标签: python objective-c swift pyobjc

大多数示例展示了如何从swift / objective-c代码调用python框架。但我想反过来,我想从python调用swift的公开函数。 有什么办法吗?

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

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

我能够找到的大多数文档似乎都集中在以下情况下:目标是将所有特定于应用程序的代码都放在python中,并且让python通过网桥调用AppKit类,等等。以及预包装的系统框架包装器。

1 个答案:

答案 0 :(得分:0)

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. 将ObjC API暴露给Python

    根据两个部分之间的接口的复杂程度,这可能很容易,也可能很困难。将ObjC类暴露给Python很容易:只需使用“ 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。