大多数示例展示了如何从swift / objective-c代码调用python框架。但我想反过来,我想从python调用swift的公开函数。 有什么办法吗?
将用Objective-C / swift编写的自定义,特定于应用程序的非系统框架(即不在PyObjC
提供的框架包装之一中)的最佳方法公开给PyObjC上的python桥。
我想开发一个“混合”应用程序,其中该应用程序的某些部分位于Objective-C / swift中,而其他部分则位于python中,并且通过PyObjC桥将其两侧集成在一起。
我能够找到的大多数文档似乎都集中在以下情况下:目标是将所有特定于应用程序的代码都放在python中,并且让python通过网桥调用AppKit类,等等。以及预包装的系统框架包装器。
答案 0 :(得分:0)
PyObjC的主要用例是从Python访问Objective-C代码,但可以使用PyObjC为Python中的ObjC / Swift应用程序实现某些功能。
这几乎没有记录。有两种解决方法:
实现对插件包的支持,并使用python代码创建插件包(使用py2app进行打包)。这是在非常古老的PyObjC教程中记录的:https://pyobjc.readthedocs.io/en/latest/tutorials/embedded.html
为应用程序的Python扩展添加显式支持。
我会选择第二个选项,因为最终这是更容易实现的选项。
要到达那里,您需要做很多事情:
初始化python解释器并运行一些启动代码。请参阅“ Py_Initialize()”和“ PyRun_SimpleString()”以进行此操作(或有关在应用程序中嵌入Python的教程)。
确保在运行启动代码后释放GIL(通常在嵌入时不是必需的,但在使用PyObjC时尤其是在不同线程可能调用Python代码时是必需的)
将ObjC API暴露给Python
根据两个部分之间的接口的复杂程度,这可能很容易,也可能很困难。将ObjC类暴露给Python很容易:只需使用“ objc.lookUpClass(classname)”即可在Python中访问ObjC类。这也会自动公开类上的所有方法。
方法访问可能需要做更多的工作,尤其是当方法具有传递引用参数或使用块时。
可以访问全局变量和C函数,但是还需要更多的工作,因为PyObjC无法从ObjC运行时API中读取这些变量。 PyObjC文档包含有关如何在需要时访问它们的信息。
在代码的Python和ObjC部分之间建立链接。我将在Python中创建Python对象,然后添加ObjC API(使用PyObjC)将其传递给应用程序的ObjC代码。
要在ObjC方面获得更好的体验,您需要在ObjC中定义将由Python代码实现的协议。
最后,请注意:所有这些都是为了从Python(而不是Swift)访问Objective-C API。这也应该与Swift代码一起使用,但前提是您必须在swift(@objc)中实现ObjC接口。 PyObjC不能用于访问任意Swift API。