Rubicon-ObjC

0.5.3 · active · verified Sat Apr 11

Rubicon-ObjC is a robust bridge between the Python and Objective-C runtime environments, enabling Python code to instantiate, invoke methods on, and subclass Objective-C classes. It's a fundamental component of the BeeWare suite for building native applications with Python. The library is actively maintained, with its current version being 0.5.3, and follows a regular release cadence to support new Python versions and fix bugs.

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to access existing Objective-C classes like `NSURL`, create instances, call methods using Pythonic syntax (handling Objective-C selectors with colons), and access properties. It also shows how to define a new Objective-C class in Python by subclassing `NSObject`, including important considerations for interactive development environments regarding class redefinition.

from rubicon.objc import ObjCClass, NSObject
import asyncio

# Access an Objective-C class (e.g., NSURL from Foundation framework)
NSURL = ObjCClass("NSURL")

# Create an instance using a static constructor method.
# Objective-C methods with ':' are mapped to Python keyword arguments or replaced with '_' in method name.
# E.g., Objective-C's +URLWithString: becomes .URLWithString_() or .URLWithString(url_string).
base_url = NSURL.URLWithString_("https://beeware.org/")
print(f"Base URL: {base_url}")

# Call another method with multiple arguments using keyword arguments
full_url = NSURL.URLWithString_relativeToURL_("contributing/", relativeToURL=base_url)
print(f"Full URL: {full_url}")

# Access Objective-C properties using Python attribute syntax
print(f"Full URL scheme: {full_url.scheme}")

# --- Defining a new Objective-C class in Python ---
# In interactive environments (like Pythonista) or when re-running code, 
# Objective-C class redefinition can cause errors. auto_rename avoids this.
ObjCClass.auto_rename = True # Set globally or pass auto_rename=True to ObjCClass() constructor

class MyPythonDelegate(NSObject):
    # Initialize the Objective-C object. Must call super().init()
    def init(self):
        self = super().init()
        if self:
            print("MyPythonDelegate initialized!")
        return self

    # Define an Objective-C method (e.g., a delegate callback)
    # Argument types should generally be annotated for clarity and correctness.
    def myDelegateMethod_withValue_(self, sender: 'id', value: int):
        print(f"Delegate method called by {sender} with value: {value}")
        return None # Objective-C methods often return `void` or `id` (None for Python)

# Instantiate the Python-defined Objective-C class
delegate_instance = MyPythonDelegate.alloc().init()

# Example of calling its method (simulating an Objective-C call)
delegate_instance.myDelegateMethod_withValue_(NSObject.alloc().init(), 42)

view raw JSON →