use std::sync::Once;
use objc::declare::ClassDecl;
use objc::runtime::{Class, Object, Sel};
use objc::{class, msg_send, sel, sel_impl};
use url::Url;
use crate::foundation::{id, nil, NSArray, NSString, NSUInteger, BOOL, NO, YES};
use crate::uikit::app::{AppDelegate, APP_DELEGATE};
use crate::uikit::scene::{SceneConfig, SceneConnectionOptions, SceneSession};
#[cfg(feature = "cloudkit")]
use crate::cloudkit::share::CKShareMetaData;
fn app<T>(this: &Object) -> &T {
unsafe {
let app = APP_DELEGATE as *const T;
&*app
}
}
extern "C" fn did_finish_launching<T: AppDelegate>(this: &Object, _: Sel, _: id, _: id) -> BOOL {
app::<T>(this).did_finish_launching();
YES
}
extern "C" fn configuration_for_scene_session<T: AppDelegate>(this: &Object, _: Sel, _: id, session: id, opts: id) -> id {
app::<T>(this)
.config_for_scene_session(SceneSession::with(session), SceneConnectionOptions::with(opts))
.into_inner()
}
pub(crate) fn register_app_delegate_class<T: AppDelegate>() -> *const Class {
static mut DELEGATE_CLASS: *const Class = 0 as *const Class;
static INIT: Once = Once::new();
INIT.call_once(|| unsafe {
let superclass = class!(NSObject);
let mut decl = ClassDecl::new("RSTAppDelegate", superclass).unwrap();
decl.add_method(
sel!(application:didFinishLaunchingWithOptions:),
did_finish_launching::<T> as extern "C" fn(&Object, _, _, id) -> BOOL
);
decl.add_method(
sel!(application:configurationForConnectingSceneSession:options:),
configuration_for_scene_session::<T> as extern "C" fn(&Object, _, _, id, id) -> id
);
DELEGATE_CLASS = decl.register();
});
unsafe { DELEGATE_CLASS }
}