Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling Python from Objective-C

I'm developing a Python/ObjC application and I need to call some methods in my Python classes from ObjC. I've tried several stuffs with no success.

  • How can I call a Python method from Objective-C?
  • My Python classes are being instantiated in Interface Builder. How can I call a method from that instance?
like image 861
gcstr Avatar asked Aug 20 '09 18:08

gcstr


1 Answers

Use PyObjC.

It is included with Leopard & later.

>>> from Foundation import *
>>> a = NSArray.arrayWithObjects_("a", "b", "c", None)
>>> a
(
      a,
      b,
      c
)
>>> a[1]
'b'
>>> a.objectAtIndex_(1)
'b'
>>> type(a)
<objective-c class NSCFArray at 0x7fff708bc178>

It even works with iPython:

In [1]: from Foundation import *

In [2]: a = NSBundle.allFrameworks()

In [3]: ?a
Type:       NSCFArray
Base Class: <objective-c class NSCFArray at 0x1002adf40>

`

To call from Objective-C into Python, the easiest way is to:

  • declare an abstract superclass in Objective-C that contains the API you want to call

  • create stub implementations of the methods in the class's @implementation

  • subclass the class in Python and provide concrete implementations

  • create a factory method on the abstract superclass that creates concrete subclass instances

I.e.

@interface Abstract : NSObject
- (unsigned int) foo: (NSString *) aBar;
+ newConcrete;
@end

@implementation Abstract
- (unsigned int) foo: (NSString *) aBar { return 42; }
+ newConcrete { return [[NSClassFromString(@"MyConcrete") new] autorelease]; }
@end

.....

class Concrete(Abstract):
    def foo_(self, s): return s.length()

.....

x = [Abstract newFoo];
[x  foo: @"bar"];
like image 144
bbum Avatar answered Sep 19 '22 05:09

bbum