Questions tagged [pyobjc]

PyObjC is a bridge between the Python and Objective-C programming languages. It allows code written in either one of those languages to interact more or less directly with code written in the other. Its primary use is in the creation of software for Mac OS X. The PyObjC package includes wrappers for Apple's Objective-C frameworks, and most of their C language APIs. It also includes project templates and file templates for use with Apple's IDE, Xcode.

PyObjC's about page explains potential advantages the bridge offers to developers in either language. The bridge allows custom Objective-C and Python code to be co-mingled (nearly) painlessly, so that each can be used where its strengths are greatest.

The most obvious advantage for Python developers is that it allows them to write applications for Mac OS X with native appearance and behaviors. The use of Apple's frameworks facilitates the creation of the expected user experience, while familiar Python modules are always available when needed. A Python class can be a subclass of any framework class.

Objective-C users may find some of their models and application logic to be easier to express succinctly in Python. In particular, the setup and access of NSArray and NSDictionary objects can be cumbersome. The bridge makes a Python list or dictionary able to be used any place that its Cocoa counterpart is expected. Python's literal lists and dictionaries, list comprehensions, iteration, and dictionary lookup syntax make sometimes awkward Objective-C constructions into elegant and readable code. Python code that uses the bridge will also manage the memory of any Cocoa object it uses.

An excellent five-part tutorial, written by Will Larson, can be found on his website, titled "An Epic Introduction to PyObjC and Cocoa". Like the bridge itself, the tutorial serves more as an introduction for Python users to Cocoa than the reverse, but is nonetheless worth reading for anyone who wants to use PyObjC.

The PyObjC Introduction goes through the basics of using the bridge. Where syntax differs, the bridge tends towards making Python code more like Objective-C code. Two syntax differences are worth singling out here: method calls and instance variable access, which can cause confusion for users of the bridge.

Objective-C's message-call syntax uses positional arguments, but the name of the method is actually interleaved with the arguments:

// The name of this method is "actOnArg:usingOtherArg:andThisOneToo:"
[anInstance actOnArg:arg1 usingOtherArg:arg2 andThisOneToo:arg3];

It seems obvious, then, to use Python's keyword argument feature to emulate this:

// The name of this method is "actOnArg", and it has keyword arguments
anInstance.actOnArg(arg1, usingOtherArg=arg2, andThisOneToo=arg3) 

However, because keyword arguments ignore position, it is not feasible to make this kind of translation. To Python, the following call is equivalent to the preceding one:

anInstance.actOnArg(arg1, andThisOneToo=arg3, usingOtherArg=arg2)

while the Objective-C call:

// The name of this method is "actOnArg:andThisOneToo:usingAnotherArg:"
[anInstance actOnArg:arg1 andThisOneToo:arg3 usingOtherArg:arg2];

refers to an entirely different method than the original example.

PyObjC's solution is to use underscores in place of colons in method names:

anInstance.actOnArg_usingOtherArg_andThisOneToo_(arg1, arg2, arg3)

which unambiguously represents the name of the Objective-C method. This, unavoidably, is one of the main warts of the bridge -- the verbosity of Cocoa method names sometimes causes unwieldy Python calls:

NSTimer.scheduledTimerWithTimeInterval_target_selector_userInfo_repeats_(1.0, self, objc.selector(self.actOnTimer_, signature='v@:@'), timerInfoDict, False)

As for instance variables, Objective-C has a separate namespace in each class for instance variables and method names, where Python has only one. A class in Objective-C can, and by convention does, have a method with the same name as an instance variable, which is a getter for that variable:

@interface MyObject : NSObject {
    int someIvar;
}
- (int)someIvar;
- (void)setSomeIvar:(int)newVal;   // The setter method for this ivar

Whereas this is impossible in Python. Python convention is to access instance variables directly, using the dot syntax:

anInstance.someIvar
anInstance.someIvar = 10

This especially causes confusion with the Objective-C 2.0 dot syntax, which is sugar for the standard accessor method:

anInstance.someIvar;         // Equivalent to [anInstance someIvar];
anInstance.someIvar = 10;    // Equivalent to [anInstance setSomeIvar:10];

PyObjC is forced to have its own convention, which is to give the ivar the name of the setter method, but prefixed with a single underscore. The convenience function objc.synthesize("someIvar") will create the ivar, the setter method, and the getter method with the expected names.

The PyObjC source is available and well worth a perusal; it especially repays investigation when getting into the trickier areas of the bridge, such as Objective-C methods which use out or plain-C parameters. In addition, the default Apple installation of PyObjC lags behind the latest version. On Snow Leopard particularly, this means that the bridge does not include some information needed to use new features of Apple's frameworks. (See "Problem with openPanelDidEnd" here on SO for an example.) That information is fortunately easily updated.

378 questions
5
votes
2 answers

Show NSPopover when the application starts

I am using Pyobjc to create a NSStatusItem. When it is clicked, I am showing an NSPopOver. This is working fine. However, my requirement is to show the popover as soon as the application starts without any action by the user. Calling the callback…
Pradeep Vairamani
  • 4,004
  • 3
  • 36
  • 59
5
votes
2 answers

How do you listen to notifications from iTunes on a Mac (Using the NSDistributedNotificationCenter)

Looking for help/tutorials/sample code of using python to listen to distributed notifications from applications on a mac. I know the py-objc lib is the bridge between python and mac/cocoa classes, and the Foundation library can be used to add…
ismail
  • 3,882
  • 5
  • 36
  • 47
5
votes
1 answer

Bundle Python framework into Xcode app

I am building a PyObjC app using Xcode 4.6.2 and am trying to figure out how to bundle the Python framework in with my app, so that I can reference it without relying on the host system having a particular Python version. (I previously asked this…
ekl
  • 1,052
  • 2
  • 9
  • 24
5
votes
0 answers

Getting USB device serial from inserted device on OSX

I am using Python 2.7 with pyobjc on Lion and NSNotification center to monitor any inserted USB volumes. This works fine. I've also got some ideas how to get a device's serial number, but these involve just parsing all the USB devices. I'd like to…
Svenito
  • 510
  • 4
  • 6
5
votes
2 answers

How can I capture iSight frames with Python in Snow Leopard?

I have the following PyObjC script: from Foundation import NSObject import QTKit error = None capture_session = QTKit.QTCaptureSession.alloc().init() print 'capture_session', capture_session device =…
Martin Blech
  • 13,135
  • 6
  • 31
  • 35
5
votes
2 answers

Has anyone successfully built a PyObjC app in Snow Leopard?

If you did, would you mind sharing how you did the pyobjc install? I was trying to do it by installing PythonMac 2.5 (for the standalone bundle thru py2app), and doing easy_install of PyObjC. I always get those deprecated errors, primarily those…
jopes
  • 245
  • 2
  • 13
5
votes
2 answers

Call a selector that takes a char* from PyObjC

I'm trying to use a private framework with PyObjC. I've got this so far: from AppKit import * from Foundation import * import objc framework="/System/Library/PrivateFrameworks/DSObjCWrappers.framework" objc.loadBundle("DSObjCWrapper", globals(),…
Clinton Blackmore
  • 2,427
  • 2
  • 24
  • 31
5
votes
1 answer

How do you use PyObjC to turn off and on the wireless interfaces of a Mac?

How do you use PyObjC to turn off and on the wireless interfaces of a Mac? My research to date has lead me to the Cocoa Framework and PyObjC. On the Mac Developer website I found an example of a wireless interface management application…
5
votes
3 answers

Code completion for MacRuby/PyObjC/RubyMotion

One of Xcode's most powerful features is it's Intellisense completion, which brings up a list of potential candidates as you type the name of a Foundation/Cocoa/UIKit API. I am very interested in MacRuby, PyObjC, or the more recent RubyMotion,…
Brian Gesiak
  • 6,648
  • 4
  • 35
  • 50
4
votes
2 answers

Setting background image of individual desktops in OSX Lion

I have a little PyObjC script to change desktop images to a particular file (which is fetched from flickr). It sets a different image for each screen, should you have multiple. This worked fine in Snow Leopard, but in Lion you can set background…
JaffaTheCake
  • 13,895
  • 4
  • 51
  • 54
4
votes
1 answer

Can python.org releases play nice with Apple framework builds?

(Advanced apologies for the lack or proper links; the system won't allow me to add more than two.) Unfortunately, I've learnt the hard way that you shouldn't mess with the default Python installations in Mac OS X (specifically, 10.6.8). After using…
4
votes
1 answer

How to install PyObjC with Python 3 and Xcode 3 on Mac OS X 10.6

I want to start using PyObjC. I've got Xcode 3 on OS X 10.6 I have both Python 3.2 and 2.6 installed, but I want to use 3.2 I've heard that PyObjC is included and that I just select it in the Xcode New Project dialog, but I don't see the option.…
Nathan
  • 6,772
  • 11
  • 38
  • 55
4
votes
4 answers

NSThread or pythons' threading module in pyobjc?

I need to do some network bound calls (e.g., fetch a website) and I don't want it to block the UI. Should I be using NSThread's or python's threading module if I am working in pyobjc? I can't find any information on how to choose one over the other.…
Yi.
  • 322
  • 3
  • 10
4
votes
1 answer

Is it possible to use pyobjc with a privilved XPC helper tool and XPCInterface API?

I believe the answer to this question is "no", but I'm putting it out to the community just in case someone has been more successful than I have. I have a privileged helper tool that a client Cocoa application uses with the NSXPCConnection and…
Corbell
  • 1,283
  • 8
  • 15
4
votes
2 answers

PyObjC and returning 'out' parameters (i.e. NSError **)

I'm implementing an ObjC protocol as a mix-in for a PyObjC class. This protocol defines an 'out' parameter. I am unable to find any good documentation on how a Python class which implements an ObjC protocol defining this is to behave. I've found…
firstresponder
  • 5,000
  • 8
  • 32
  • 38