NSPython is a simple Python library for using Objective C, Foundation and Application Kit Frameworks, also known as Cocoa.
Install
Copy the package to Python search path and that should be it.
It requires cffi, a Foreign Function Interface package for calling C libraries from Python.
Overview
Objective C:
@"hello"
@selector(setDelegate:)
[myObject delegate];
[myObject setVariable:YES anotherVariable:NO];
[NSString stringWithUTF8String:"hello"];
[[[NSString alloc] initWithUTF8String:"hello"] autorelease];
[super init];
With NSPython you instead say:
at('hello')
sel('setDelegate:')
myObject.delegate()
myObject.setVariable_anotherVariable_(True, False)
NSString.stringWithUTF8String_('hello')
NSString.alloc().initWithUTF8String_('hello').autorelease()
get_super(self).init()
Subclassing
To make the methods of your subclass recognizable by Objective C runtime there are two possibilities. If you override a method already present in the superclass, you are done. But if you define completely new method you have to decorate it with type annotations:
class MyString(NSString):
def initWithUTF8String_(self, string): pass
@types('id', 'char *')
@classmethod
def anotherStringWithUTF8String_(self, string): pass
@types('id', 'char *')
def anotherInitWithUTF8String_(self, string): pass
Here is the list of the supported types (for objects just use id, instead of, say, NSString *):
BOOL, BOOL *, int, short, long, long long, long long *, unsigned char, unsigned int, unsigned short, unsigned short *, const unsigned short *, unsigned long, unsigned long long, unsigned long long *, float, double, double *, void, void *, const void *, char *, char **, const char *, unichar *, const unichar *, id, id *, Class, SEL, NSInteger, NSUInteger, NSRange, NSRange *, NSRangePointer, CGPoint, CGSize, CGRect, NSPoint, NSSize, NSRect
Example
(based on Minimalist Cocoa programming)
from nspython import *
class AppDelegate(NSObject):
@types('void', 'id')
def applicationWillFinishLaunching_(self, notification):
print 'Hello!'
NSAutoreleasePool.new()
app = NSApplication.sharedApplication()
app.setActivationPolicy_(NSApplicationActivationPolicyRegular)
appdelegate = AppDelegate.new()
app.setDelegate_(appdelegate)
menubar = NSMenu.new().autorelease()
appMenuItem = NSMenuItem.new().autorelease()
menubar.addItem_(appMenuItem)
app.setMainMenu_(menubar)
appMenu = NSMenu.new().autorelease()
appName = NSProcessInfo.processInfo().processName()
quitTitle = at('Quit ').stringByAppendingString_(appName)
quitMenuItem = NSMenuItem.alloc().initWithTitle_action_keyEquivalent_(
quitTitle, sel('terminate:'), at('q')).autorelease()
appMenu.addItem_(quitMenuItem)
appMenuItem.setSubmenu_(appMenu)
window = NSWindow.alloc().initWithContentRect_styleMask_backing_defer_(
NSMakeRect(0, 0, 200, 200),
NSTitledWindowMask,
NSBackingStoreBuffered,
False).autorelease()
window.cascadeTopLeftFromPoint_(NSMakePoint(20, 20))
window.setTitle_(appName)
window.makeKeyAndOrderFront_(None)
app.activateIgnoringOtherApps_(True)
app.run()
Reference
load(name) -- loads a dynamic library named name
sel(name) -- returns a selector named name
types(return, *arguments) -- decorator for creating type annotations with return type return and zero or more arguments types.
@IBAction -- shorthand for @types('void', 'id')
NSObject -- Python wrapper around Cocoa NSObject
get_super(self) -- substitute for Objective C super keyword
at(string) -- creates NSString instance from Python string
str(string) -- converts NSString string to Python
Notes
If you create a struct with, say, NSMakeRect() you have to be careful with the ownership of the allocated memory. That is, this will not work:
currentScrollPosition = theScrollView.contentView().bounds().origin
theScrollView.documentView().scrollPoint_(currentScrollPosition)
because the NSRect returned from bound() might get garbage-collected, destroying origin as well. Instead, write it as follows:
b = theScrollView.contentView().bounds()
theScrollView.documentView().scrollPoint_(b.origin)
Product's homepage
Requirements:
· Python