在Xcode项目中运行Python文件

2,279 阅读2分钟

为什么要扯到在Xcode的项目中运行python文件,是因为写的一个抢票软件抢票逻辑是使用python编写,UI部分是使用Xcode写的mac端。刚开始mac端和python文件之间的交互不是实时的,自己刚开始学python,所以这一块就更麻烦了,导致刚开始的思路是mac端用Timer在某个点刷新配置文件,这就有点要吐血了。

一、思路-->跳一跳助手

前一段时间下载了别人的跳一跳的辅助助手脚本,那个脚本文件里有import cv2,在终端直接使用python命令运行脚本文件就能直接运行。基于这个助手的思路,Xcode有提供API能运行脚本文件且不用improt cv2 或是其他第三方模块,那上面的问题就迎刃而解了。

二、动手

google了一会,发现NSTask和system不时地被提到,在mac端试着运行了代码system(path),xcode提示我swift3适用Process,那就去解了下如何使用Process呗,第一次使用的时候代码如下:

    let task = Process()
    task.launchPath = "/usr/bin/python"
    task.arguments = ["/Users/**/Desktop/TestPython/pythonFile/main.py"]
    task.launch()

三、报错

报错的提示 No module such as requests,也就是说这么执行不能自动import 第三方module,google的找思路过程中突然想到,公司电脑里该项目的Python interpreter是自己根据网上的教程创建的一个venv文件夹里的python版本,上面的代码中task的launchPath是"/usr/bin/python",这不难看出是安装python时自动创建的目录,进入该目录看到该文件图标是这样的:

有没有像终端的图标?launch on this path,将自动安装的后在系统目录的python文件或是虚拟环境的python文件给了launchpath。

四、再次尝试

再次运行,在xcode的console里面看到了该python文件里面的print参数,好吧,终于能在xcode代码里运行python文件了。

五、收尾

最后一个问题,如何知道运行结束了?进入Process API,发现了didTerminateNotification这么个常量,好吧,是通知的形式,也有terminationHandler: ((Process) -> Void)? 这样的block形式,有个人的经验是这样的,如何知道那个是哪个Process完成了呢,很简单:

@objc func taskTerminated(_ noti:NSNotification){
        if let task = noti.object as? Process {
            print(task.arguments)
        }
    }

Done.

Tips: 1.第一次launch有点慢。 2.python里的os.getcwd()在xcode里运行会是xcode app的相对路径,所以要注意啦。 3.貌似fackbook的那个框架好像能做一些好玩的东西

参考文章:

Mac OSX 开发入门基础系列之NSTask

我用Xcode +python写的第一个OS X app

NSTask Tips (Swift)

virtualenv

如何在 Swift 3.0 中使用 Process 调用外部命令

教你如何用Swift编写Xcode插件