diff --git a/Cargo.toml b/Cargo.toml index 9912e44..d1f4e00 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,9 +36,9 @@ jni = "0.21" ndk-context = "0.1" [target.'cfg(any(target_os = "ios", target_os = "tvos", target_os = "visionos"))'.dependencies] -block2 = "0.5.0" -objc2 = "0.5.1" -objc2-foundation = { version = "0.2.0", default-features = false, features = [ +block2 = "0.6.0" +objc2 = "0.6.0" +objc2-foundation = { version = "0.3.0", default-features = false, features = [ "std", "NSDictionary", "NSString", diff --git a/src/ios.rs b/src/ios.rs index ea926d4..a9cff6e 100644 --- a/src/ios.rs +++ b/src/ios.rs @@ -1,12 +1,20 @@ use crate::{Browser, BrowserOptions, Error, ErrorKind, Result, TargetType}; use block2::Block; -use objc2::rc::Id; +use objc2::rc::Retained; use objc2::runtime::Bool; -use objc2::{class, msg_send, msg_send_id}; +use objc2::{class, msg_send, MainThreadMarker}; use objc2_foundation::{NSDictionary, NSObject, NSString, NSURL}; -fn app() -> Option> { - unsafe { msg_send_id![class!(UIApplication), sharedApplication] } +fn app(mtm: MainThreadMarker) -> Option> { + let _ = mtm; + // SAFETY: The signature is correct, and we hold `MainThreadMarker`, so we + // know we're on the main thread where it's safe to access the shared + // UIApplication. + // + // NOTE: `sharedApplication` is declared as returning non-NULL, but it + // will only do so inside `UIApplicationMain`; if called outside, the + // shared application is NULL. + unsafe { msg_send![class!(UIApplication), sharedApplication] } } fn open_url( @@ -29,12 +37,19 @@ pub(super) fn open_browser_internal( // ensure we're opening only http/https urls, failing otherwise let url = target.get_http_url()?; + let mtm = MainThreadMarker::new().ok_or_else(|| { + Error::new( + ErrorKind::Other, + "Cannot open URL from a thread that is not the main thread", + ) + })?; + // always return true for a dry run if options.dry_run { return Ok(()); } - let app = app().ok_or(Error::new( + let app = app(mtm).ok_or(Error::new( ErrorKind::Other, "UIApplication is null, can't open url", ))?;