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
4
votes
4 answers

PyObjC / Ruby bridge. Is it worthwhile ?

Years ago wanting to write Mac software and having loads of experience with Java WebObjects I tried the java bridge but decided to bite the bullet and learn Objective-C (fortunately since I would have hated having my software deprecated with the…
team-rf
  • 241
  • 1
  • 7
4
votes
1 answer

Python PyObjC_IdToPython(@protocol(NSURLSessionStreamDelegate)) error

when i try to install pyobjc-framework-Cocoa i see this error: In file included from Modules/_Foundation.m:15: Modules/_Foundation_protocols.m:14:28: error: cannot find protocol declaration for 'NSProgressReporting' p =…
4
votes
1 answer

errorr installing pyobjc on Anaconda python on OSX 10.10.2

I have Python 3.3.5 :: Anaconda 2.1.0 (x86_64) on Mac OS X 10.10.2 with XCode 6.2 (6C131e) and pip 6.0.8 I'm trying to install PyObjC following the guide. However when I do pip install -U pyobjc I get the following error: $ pip install -U…
Fra
  • 4,918
  • 7
  • 33
  • 50
4
votes
1 answer

Using Appkit and Python to hide mouse cursor on OSX

I'm trying to script hiding the mouse cursor on OSX 10.9. I have Chrome starting and going full screen for a kiosk and I'd like to periodically run a script to hide the cursor. Applescript no longer directly supports "call method" to call the…
rrauenza
  • 6,285
  • 4
  • 32
  • 57
4
votes
1 answer

pyobjc and wx crash when program exits ends

Similar to this question wxPython + PyObjC causes app to crash at the end however there code has more superfluous code. I have the following two samples of code, the latter crashes the former runs fine. The only difference in the code is the order…
Zimm3r
  • 3,369
  • 5
  • 35
  • 53
4
votes
1 answer

How do I make Interface Builder recognize IBOutlet/IBAction for new languages?

it's a theoretical question: suppose I come up with an outstanding new scripting language and want to make a Cocoa bridge for that. Is it possible to make Interface Builder recognize the new language and parse the source code automatically so that…
Yuji
  • 34,103
  • 3
  • 70
  • 88
4
votes
1 answer

How to build a PyObjC project on Mac OS X 10.6, that runs 10.5?

I have a PyObjC project that I build on Mac OS X 10.6 with XCode 3.2 and I'm not able to run on 10.5. All I'm using is the official PyObjC project templates to create an empty project (that simply opens a window). Then I build the app and copy it…
hupf
  • 604
  • 1
  • 6
  • 10
4
votes
2 answers

How do you call PyObjC code from Objective-C?

Possible Duplicate: Calling Python from Objective-C I'm a long-time Python programmer and short-time Cocoa programmer. I'm just getting started with PyObjC and it's really amazing how easy it it is to get stuff done. That said, I wanted to try…
zekel
  • 9,227
  • 10
  • 65
  • 96
4
votes
2 answers

Python capture Keystrokes values in text file on OS X

I am trying to monitor keystrokes on my Macbook on order to build a statistics analyzer. But how can I isolate the chars from "event" which is more something like : NSEvent: type=KeyDown loc=(850,248) time=66551.8 flags=0x100 win=0x0 winNum=0…
Carto_
  • 577
  • 8
  • 28
3
votes
2 answers

Getting the active application on OS X 10.7 using a python daemon

I'm trying to build a daemon in python and I want to get the name of the current active application. For the daemon I'm using this nice code snipped from Sander Marechal The following line works perfectly on OS X 10.7 when I DON'T run the…
kadrian
  • 4,761
  • 8
  • 39
  • 61
3
votes
1 answer

Implementing NSText delegate methods in PyObjc and Cocoa

In the project that I'm building, I'd like to have a method called when I paste some text into a specific text field. I can't seem to get this to work, but here's what I've tried I implimented a custom class (based on NSObject) to be a delegate for…
Tom Crayford
  • 527
  • 6
  • 10
3
votes
3 answers

Calling a PyObjc function from Javascript

EDIT Since I posted the question I have found another working Objc example(http://mattgemmell.com/2008/02/24/skinnable-cocoa-ui-with-webkit-and-css + source: http://mattgemmell.com/files/source/skinnableapp.zip) This is what I have…
Stelian
  • 181
  • 1
  • 5
3
votes
4 answers

Unicode problems in PyObjC

I am trying to figure out PyObjC on Mac OS X, and I have written a simple program to print out the names in my Address Book. However, I am having some trouble with the encoding of the output. #! /usr/bin/env python # -*- coding: UTF-8 -*- from…
gustavlarson
  • 417
  • 3
  • 8
3
votes
1 answer

Segfault in simple 2-line NSCountWindows call?

I'm trying to get window handles to currently available windows using PyObjC, with Mac OS X 10.7 and default Python 2.7. However, the following 2-liner causes Python to crash immediately. What gives? bash-3.2$ python Python 2.7.1 (r271:86832, Jul 31…
Jerry Chong
  • 563
  • 2
  • 9
  • 19
3
votes
3 answers

BWSplitView and PyObjc

I'm trying to use Brandon Walkin's BWSplitView from BWToolkit in a Cocoa PyObjc project. When I run the project I get the following error message: NSInvalidUnarchiveOperationException - *** -[NSKeyedUnarchiver decodeObjectForKey:]: cannot decode…
Tom Crayford
  • 527
  • 6
  • 10