use std::ffi::c_void;
use objc2::{class, msg_send, rc::Retained, Encode, Encoding, MainThreadMarker};
use objc2_foundation::{NSDictionary, NSObject, NSString, NSURL};
use crate::{Browser, BrowserOptions, Error, Result, TargetType};
#[allow(non_snake_case)]
fn sharedApplication(mtm: MainThreadMarker) -> Option<Retained<NSObject>> {
let _ = mtm;
unsafe { msg_send![class!(UIApplication), sharedApplication] }
}
#[repr(transparent)]
struct FakeBlock(*const c_void);
unsafe impl Encode for FakeBlock {
const ENCODING: Encoding = Encoding::Block;
}
#[doc(alias = "openURL_options_completionHandler")]
fn open_url(app: &NSObject, url: &NSURL, options: &NSDictionary) {
let fake_handler = FakeBlock(std::ptr::null());
unsafe { msg_send![app, openURL: url, options: options, completionHandler: fake_handler] }
}
pub(super) fn open_browser_internal(
_browser: Browser,
target: &TargetType,
options: &BrowserOptions,
) -> Result<()> {
let url = target.get_http_url()?;
if options.dry_run {
return Ok(());
}
let mtm = MainThreadMarker::new().ok_or(Error::other(
"UIApplication must be retrieved on the main thread",
))?;
let app = sharedApplication(mtm).ok_or(Error::other(
"UIApplication is NULL, perhaps UIApplicationMain has not been executed?",
))?;
let url_string = NSString::from_str(url);
#[allow(unused_unsafe)] let url_object = unsafe { NSURL::URLWithString(&url_string) }
.ok_or(Error::other("Failed creating NSURL; is the URL valid?"))?;
let options = NSDictionary::new();
open_url(&app, &url_object, &options);
Ok(())
}