PyObjC is a bridge between Python and Objective-C that allows full featured Cocoa applications to be written in pure Python.
—
Decorators and utilities for creating Objective-C methods, defining method signatures, creating categories, and handling protocol conformance. These tools are essential for creating Python classes that integrate seamlessly with Objective-C.
Decorators for defining and managing Objective-C method signatures and type information.
def signature(signature: str):
"""
Decorator to set the Objective-C type signature for a method.
Args:
signature (str): Objective-C type encoding string
Usage:
@objc.signature(b'v@:i')
def setIntValue_(self, value):
self._value = value
"""
def callbackFor(signature: str):
"""
Decorator to mark a function as a callback with a specific signature.
Args:
signature (str): Objective-C type encoding for the callback
Usage:
@objc.callbackFor(b'v@:@')
def completion_handler(result):
print(f"Completed with: {result}")
"""
def selectorFor(signature: str):
"""
Decorator to create a selector from a signature.
Args:
signature (str): Method signature to create selector for
"""
def typedSelector(signature: str):
"""
Decorator to create a typed selector with explicit signature.
Args:
signature (str): Complete type signature for the selector
"""
def namedSelector(name: str, signature: str = None):
"""
Decorator to create a selector with a specific name and optional signature.
Args:
name (str): The selector name to use
signature (str, optional): Type signature for the selector
Usage:
@objc.namedSelector("performAction:withObject:", signature="v@:@@")
def doSomething_withThing_(self, action, thing):
pass
"""
def accessor(func, typeSignature: str):
"""
Decorator to create a property accessor with type signature.
Args:
func: The accessor function
typeSignature (str): Objective-C type encoding
Usage:
@objc.accessor
def getTitle(self):
return self._title
"""
def typedAccessor(typeSignature: str):
"""
Decorator to create a typed property accessor.
Args:
typeSignature (str): Objective-C type encoding
Usage:
@objc.typedAccessor("@")
def title(self):
return self._title
"""
def callbackPointer(closure):
"""
Create a callback pointer from a closure.
Args:
closure: The closure to convert to a pointer
Returns:
Callback pointer suitable for C function calls
Usage:
def my_callback(value):
print(f"Callback: {value}")
ptr = objc.callbackPointer(my_callback)
"""Decorators for marking methods as class methods or instance methods in the Objective-C sense.
def classmethod(func):
"""
Use Python's built-in classmethod decorator for Objective-C class methods.
Args:
func: The method to mark as a class method
Note: PyObjC uses Python's built-in classmethod decorator, not objc.classmethod
Usage:
@classmethod
def sharedInstance(cls):
return cls.alloc().init()
"""
def instancemethod(func):
"""
Decorator to mark a method as an Objective-C instance method.
Args:
func: The method to mark as an instance method
Usage:
@objc.instancemethod
def doSomething(self):
pass
"""Decorators and functions for adding methods to existing Objective-C classes via categories.
def category(baseClass):
"""
Decorator to add category methods to an existing Objective-C class.
Args:
baseClass: The Objective-C class to extend
Usage:
@objc.category(NSString)
class NSStringExtensions:
def isPythonic(self):
return self.hasPrefix_("py")
"""
def synthesize(name: str, copy: bool = False, readwrite: bool = True, type: str = None, ivar: str = None):
"""
Decorator to synthesize property accessors.
Args:
name (str): Property name to synthesize
copy (bool): Whether to use copy semantics
readwrite (bool): Whether the property is read-write
type (str): Type encoding for the property
ivar (str): Instance variable name
Usage:
@objc.synthesize('title', copy=True)
@objc.synthesize('count', type='i')
class MyClass(NSObject):
pass
"""Decorators for Interface Builder integration and designable views.
def IBOutlet(name: str = None):
"""
Create an Interface Builder outlet property.
Args:
name (str, optional): Name for the outlet
Usage:
myButton = objc.IBOutlet()
customLabel = objc.IBOutlet("titleLabel")
"""
def IBAction(func):
"""
Decorator to mark a method as an Interface Builder action.
Args:
func: The method to mark as an IBAction
Usage:
@objc.IBAction
def buttonClicked_(self, sender):
print("Button was clicked!")
"""
def IBInspectable(func):
"""
Decorator to mark a property as inspectable in Interface Builder.
Args:
func: The property method to mark as inspectable
Usage:
@objc.IBInspectable
def cornerRadius(self):
return self._cornerRadius
"""
def IB_DESIGNABLE(cls):
"""
Decorator to mark a class as designable in Interface Builder.
Args:
cls: The class to mark as designable
Usage:
@objc.IB_DESIGNABLE
class MyCustomView(NSView):
pass
"""Property descriptor classes for different data types and behaviors.
def object_property(name: str = None, ivar: str = None, copy: bool = False, **kwargs):
"""
Create an object property descriptor.
Args:
name (str): Property name
ivar (str): Instance variable name
copy (bool): Use copy semantics
**kwargs: Additional property attributes
Usage:
title = objc.object_property(copy=True)
"""
def bool_property(name: str = None, ivar: str = None, **kwargs):
"""
Create a boolean property descriptor.
Args:
name (str): Property name
ivar (str): Instance variable name
**kwargs: Additional property attributes
Usage:
isEnabled = objc.bool_property()
"""
def array_property(name: str = None, ivar: str = None, copy: bool = False, **kwargs):
"""
Create an array property descriptor.
Args:
name (str): Property name
ivar (str): Instance variable name
copy (bool): Use copy semantics
**kwargs: Additional property attributes
Usage:
items = objc.array_property(copy=True)
"""
def set_property(name: str = None, ivar: str = None, copy: bool = False, **kwargs):
"""
Create a set property descriptor.
Args:
name (str): Property name
ivar (str): Instance variable name
copy (bool): Use copy semantics
**kwargs: Additional property attributes
Usage:
tags = objc.set_property(copy=True)
"""
def dict_property(name: str = None, ivar: str = None, copy: bool = False, **kwargs):
"""
Create a dictionary property descriptor.
Args:
name (str): Property name
ivar (str): Instance variable name
copy (bool): Use copy semantics
**kwargs: Additional property attributes
Usage:
metadata = objc.dict_property(copy=True)
"""Advanced decorators for specialized method handling and closure support.
class Accessor:
"""
Generic accessor descriptor for Objective-C properties.
Provides flexible property access patterns with automatic
getter/setter generation and type conversion.
"""
class ivar:
"""
Instance variable descriptor for Objective-C classes.
Provides direct access to Objective-C instance variables from Python
with proper type conversion and memory management.
"""
def _makeClosure(callable, signature: str):
"""
Create a closure for callback functions.
Args:
callable: The Python function to wrap
signature (str): Objective-C type signature
Returns:
Closure object suitable for callback usage
"""
def _closurePointer(closure):
"""
Get the pointer for a closure object.
Args:
closure: The closure object
Returns:
Pointer to the closure implementation
"""Decorators for version checking and context management.
def macos_available(major: int, minor: int = 0, patch: int = 0):
"""
Decorator to check macOS version availability.
Args:
major (int): Major version number
minor (int): Minor version number (default: 0)
patch (int): Patch version number (default: 0)
Usage:
@objc.macos_available(10, 15)
def useNewAPI(self):
# Only available on macOS 10.15+
pass
"""
def os_available(*args):
"""
Decorator to check OS availability across platforms.
Args:
*args: Version requirements for different platforms
"""import objc
from Foundation import NSObject
class MyCustomClass(NSObject):
@objc.synthesize('title')
@objc.synthesize('count')
def init(self):
self = objc.super(MyCustomClass, self).init()
if self is None:
return None
self.setTitle_("Default Title")
self.setCount_(0)
return self
@objc.signature(b'v@:i')
def incrementCountBy_(self, amount):
self.setCount_(self.count() + amount)
@objc.classmethod
def sharedInstance(cls):
if not hasattr(cls, '_shared'):
cls._shared = cls.alloc().init()
return cls._sharedimport objc
from Foundation import NSString
@objc.category(NSString)
class NSStringPythonExtensions:
def isPythonic(self):
return self.hasPrefix_("py") or self.hasSuffix_(".py")
@objc.signature(b'@@:@')
def stringByAppendingPythonSuffix_(self, suffix):
return self.stringByAppendingFormat_("_py_%@", suffix)Install with Tessl CLI
npx tessl i tessl/pypi-pyobjc