I'm trying to run a Python script from a Cocoa app. It's working just fine on the main thread, but I'd like to have it running in the background, on a concurrent GCD queue.
I'm using the following method to setup a manager class that runs the Python script:
- (BOOL)setupPythonEnvironment {
if (Py_IsInitialized()) return YES;
Py_SetProgramName("/usr/bin/python");
Py_Initialize();
NSString *scriptPath = [[NSBundle mainBundle] pathForResource:@"MyScript" ofType:@"py"];
FILE *mainFile = fopen([scriptPath UTF8String], "r");
return (PyRun_SimpleFile(mainFile, (char *)[[scriptPath lastPathComponent] UTF8String]) == 0);
}
After which the script is (repeatedly) called from the following instance method, using a shared singleton instance of the manager class:
- (id)runScriptWithArguments:(NSArray *)arguments {
return [NSClassFromString(@"MyScriptExecutor") runWithArguments:arguments];
}
The above Objective-C code hooks into the following Python code:
from Foundation import *
def run_with_arguments(arguments):
# ...a long-running script
class MyScriptExecutor(NSObject):
@classmethod
def runWithArguments_(self, arguments):
return run_with_arguments(arguments)
This works when I always run the above Objective-C methods from the main queue, but the script returns null when run from any other queue. Could someone explain me if what I'm trying to do is just not supported, and whether there's a good way around it?
The Python scripts is called often and runs long, so doing that on the main thread would be too slow, a would be running it form a serial queue. In addition, I'd like to contain the concurrency code within Objective-C as much as possible.
Thanks,