#![deny(unsafe_op_in_unsafe_fn)] use objc2::rc::Retained; use objc2::runtime::ProtocolObject; use objc2::{declare_class, msg_send_id, mutability, ClassType, DeclaredClass}; use objc2_app_kit::{NSApplication, NSApplicationActivationPolicy, NSApplicationDelegate}; use objc2_foundation::{ ns_string, MainThreadMarker, NSCopying, NSNotification, NSObject, NSObjectProtocol, NSString, }; #[derive(Debug)] #[allow(unused)] struct Ivars { ivar: u8, another_ivar: bool, box_ivar: Box, maybe_box_ivar: Option>, id_ivar: Retained, maybe_id_ivar: Option>, } declare_class!( struct AppDelegate; // SAFETY: // - The superclass NSObject does not have any subclassing requirements. // - Main thread only mutability is correct, since this is an application delegate. // - `AppDelegate` does not implement `Drop`. unsafe impl ClassType for AppDelegate { type Super = NSObject; type Mutability = mutability::MainThreadOnly; const NAME: &'static str = "MyAppDelegate"; } impl DeclaredClass for AppDelegate { type Ivars = Ivars; } unsafe impl NSObjectProtocol for AppDelegate {} unsafe impl NSApplicationDelegate for AppDelegate { #[method(applicationDidFinishLaunching:)] fn did_finish_launching(&self, notification: &NSNotification) { println!("Did finish launching!"); // Do something with the notification dbg!(notification); } #[method(applicationWillTerminate:)] fn will_terminate(&self, _notification: &NSNotification) { println!("Will terminate!"); } } ); impl AppDelegate { fn new(ivar: u8, another_ivar: bool, mtm: MainThreadMarker) -> Retained { let this = mtm.alloc(); let this = this.set_ivars(Ivars { ivar, another_ivar, box_ivar: Box::new(2), maybe_box_ivar: None, id_ivar: NSString::from_str("abc"), maybe_id_ivar: Some(ns_string!("def").copy()), }); unsafe { msg_send_id![super(this), init] } } } fn main() { let mtm: MainThreadMarker = MainThreadMarker::new().unwrap(); let app = NSApplication::sharedApplication(mtm); app.setActivationPolicy(NSApplicationActivationPolicy::Regular); // configure the application delegate let delegate = AppDelegate::new(42, true, mtm); let object = ProtocolObject::from_ref(&*delegate); app.setDelegate(Some(object)); // run the app unsafe { app.run() }; }