@mikael I'm not very creative with these things - do you have some example code based on objc_util that I could translate to Rubicon?
In general the syntax for classes looks like this:
from rubicon.objc import NSInteger, NSObject, ObjCProtocol, objc_method WhateverDelegate = ObjCProtocol("WhateverDelegate") class MyCustomDelegate(NSObject, protocols=[WhateverDelegate]): # the protocols=[...] part is optional of course, if you don't need to implement any protocol @objc_method def someThing_didAThingWithCount_(self, something, count: NSInteger) -> None: print(something, count) something.delegate = MyCustomDelegate.new()The Python 3 type annotation syntax is used to set each method's return and argument types. You use regular ctypes type objects for the types, and Rubicon predefines some common typedefs like NSInteger. Anything you don't annotate is assumed to be an Objective-C object (ObjCInstance).
Blocks are similar:
from rubicon.objc import Block, NSInteger @Block def thing_callback(number: NSInteger) -> None: print(number) whatever.doThing("abc", withCallback=callback)