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

finding the app window currently in focus on Mac OSX

I am writing a desktop usage statistics app. It runs a background daemon which wakes up at regular intervals, finds the name of the application window currently in focus and logs that data in database. I manage to do this on Linux desktop with help…
Jayesh
  • 51,787
  • 22
  • 76
  • 99
6
votes
1 answer

PyObjC and custom blocks

The official documentation says that it is possible to use custom blocks in python code but you need to create metadata. I haven't found an example of it. My question is how to create, use and distribute metadata for custom…
Kentzo
  • 3,881
  • 29
  • 54
6
votes
2 answers

PyObjC tutorial without Xcode

I'm writing a small cross-platform wxPython app, however on every platform I need to use some platform-specific API. On Mac OS it can be done using PyObjC. I'm searching for tutorial on how to use PyObjC. However, all I found so far were tutorials…
Vladimir Keleshev
  • 13,753
  • 17
  • 64
  • 93
6
votes
2 answers

Writing metadata to a pdf using pyobjc

I'm trying to write metadata to a pdf file using the following python code: from Foundation import * from Quartz import * url = NSURL.fileURLWithPath_("test.pdf") pdfdoc = PDFDocument.alloc().initWithURL_(url) assert pdfdoc, "failed to create…
djq
  • 14,810
  • 45
  • 122
  • 157
6
votes
1 answer

How to connect to a Wi-Fi network using Python on OS X?

I want to connect to a Wi-Fi network using Python on OS X (10.11). Based on CWInterface reference I figured out there is a iface.associateToNetwork_password_error_() method available, however when called it does not connect to the network nor it…
techraf
  • 64,883
  • 27
  • 193
  • 198
6
votes
2 answers

Compiling a PyObjC application for 10.5 (Leopard) into xcode 10.6 (Snow Leopard)

I'm trying to deploy on 10.5 a PyObjC (or Cocoa-Python) application developed on Xcode 3.2.X (Snow Leopard) which runs perfectly fine on 10.6 systems. The application doesn't launch on 10.5;it crashes at launch giving this error message (found on…
Fabio Cionini
  • 767
  • 6
  • 15
6
votes
1 answer

NSUserNotificationCenter.defaultUserNotificationCenter() returns None in python

I am trying to connect to the Mountain Lion notification center via python. I've installed pyobjc and am following the instructions here and here. Also see: Working with Mountain Lion's Notification Center using PyObjC Here's my code: import…
6
votes
1 answer

What is the best way to sample/profile a PyObjC application?

Sampling with Activity Monitor/Instruments/Shark will show stack traces full of C functions for the Python interpreter. I would be helpful to see the corresponding Python symbol names. Is there some DTrace magic that can do that? Python's cProfile…
Michael Tsai
  • 1,945
  • 17
  • 41
6
votes
5 answers

XCode 3.2 Ruby and Python templates

Under xcode 3.2 my ObjectiveC + Python/Ruby projects can still be opened updated and compiled, but you cannot create new projects. Given that all traces of ruby and python are missing from xcode 3.2 (ie create project and add new ruby/python file),…
Jay
  • 19,649
  • 38
  • 121
  • 184
5
votes
1 answer

Accessing iPhone Accelerometer using PyObjC

I want to access the Accelerometer of my iPhone through PyObjC. Here is my Code: @objc.signature("v@:@@") def accelerometer_didAccelerate_(self, accelerometer, acceleration): msgBox =…
Chris
  • 51
  • 2
5
votes
1 answer

What is PyObjC?

I understand the concept of PyObjC, but can nowhere find any information on what exactly it is or how to get started with it. Is it like a converter, where youinput python files and get an objective c one? Or is it a library you can import to your…
lavelle
  • 1,446
  • 1
  • 17
  • 30
5
votes
2 answers

Getting python exceptions printed the normal way with PyObjC

I'm getting errors like this: 2010-07-13 20:43:15.131 Python[1527:60f] main: Caught OC_PythonException: : LoginMenuSet instance has no attribute 'play_sound' That's with this code: @try { [section loop]; //Loop through section } @catch…
Matthew Mitchell
  • 5,293
  • 14
  • 70
  • 122
5
votes
1 answer

Growl Python binding with Click feedback?

I'm trying to use the Growl Python bindings (Growl.py v0.7 from the Growl repository) to write a small application. One of the features that's currently missing is the click notification sent to Python. I know in Objective-C, when a user clicks the…
Patrick
  • 4,186
  • 9
  • 32
  • 45
5
votes
2 answers

How to change the OSX menubar in wxPython without any opened window?

I am writing a wxPython application that remains open after closing all of its windows - so you can still drag & drop new files onto the OSX dock icon (I do this with myApp.SetExitOnFrameDelete(False)). Unfortunately if I close all the windows, the…
gyim
  • 8,803
  • 2
  • 19
  • 21
5
votes
0 answers

Detect change in frontmost application in OS X with Python

I have created an application using pyobjc to monitor the current application I'm using or current URL if Safari/Chrome are being used. I get the frontmost application using: active_app_name =…
user2317421
1 2
3
25 26