Skip to content

Commit f287749

Browse files
committed
ios: Upgrade to objc2 0.6 and drop dependency on block2
Even though there's a new `objc2-ui-kit` dependency available that represents the `UIApplication` type and its methods faithfully, there was a strong preference to cut down on the number of dependencies instead so its improved signature has been incorporated here. By extension the `block2` crate was removed too by inlining a simple type definition just to be able to set the `Option<&Block>` to `None`.
1 parent 3ea6f97 commit f287749

File tree

2 files changed

+28
-20
lines changed

2 files changed

+28
-20
lines changed

Cargo.toml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,8 @@ jni = "0.21"
3636
ndk-context = "0.1"
3737

3838
[target.'cfg(any(target_os = "ios", target_os = "tvos", target_os = "visionos"))'.dependencies]
39-
block2 = "0.5.0"
40-
objc2 = "0.5.1"
41-
objc2-foundation = { version = "0.2.0", default-features = false, features = [
39+
objc2 = "0.6"
40+
objc2-foundation = { version = "0.3", default-features = false, features = [
4241
"std",
4342
"NSDictionary",
4443
"NSString",

src/ios.rs

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,29 @@
1-
use crate::{Browser, BrowserOptions, Error, ErrorKind, Result, TargetType};
2-
use block2::Block;
3-
use objc2::rc::Id;
4-
use objc2::runtime::Bool;
5-
use objc2::{class, msg_send, msg_send_id};
1+
use std::ffi::c_void;
2+
3+
use objc2::{class, msg_send, rc::Retained, Encode, Encoding, MainThreadMarker};
64
use objc2_foundation::{NSDictionary, NSObject, NSString, NSURL};
75

8-
fn app() -> Option<Id<NSObject>> {
9-
unsafe { msg_send_id![class!(UIApplication), sharedApplication] }
6+
use crate::{Browser, BrowserOptions, Error, ErrorKind, Result, TargetType};
7+
8+
/// Returns `UIApplication`
9+
#[allow(non_snake_case)]
10+
fn sharedApplication(_mtm: MainThreadMarker) -> Retained<NSObject> {
11+
unsafe { msg_send![class!(UIApplication), sharedApplication] }
12+
}
13+
14+
/// Fake `block` to not have to depend on the `block2` crate just to set this to an empty/`None` block.
15+
#[repr(transparent)]
16+
struct FakeBlock(*const c_void);
17+
18+
// SAFETY: The type is `#[repr(transparent)]` over a pointer (same layout as `Option<&block::Block<...>>`).
19+
unsafe impl Encode for FakeBlock {
20+
const ENCODING: Encoding = Encoding::Block;
1021
}
1122

12-
fn open_url(
13-
app: &NSObject,
14-
url: &NSURL,
15-
options: &NSDictionary,
16-
handler: Option<&Block<dyn Fn(Bool)>>,
17-
) {
18-
unsafe { msg_send![app, openURL: url, options: options, completionHandler: handler] }
23+
#[doc(alias = "openURL_options_completionHandler")]
24+
fn open_url(app: &NSObject, url: &NSURL, options: &NSDictionary) {
25+
let fake_handler = FakeBlock(std::ptr::null());
26+
unsafe { msg_send![app, openURL: url, options: options, completionHandler: fake_handler] }
1927
}
2028

2129
/// Deal with opening of browsers on iOS/tvOS/visionOS.
@@ -34,10 +42,11 @@ pub(super) fn open_browser_internal(
3442
return Ok(());
3543
}
3644

37-
let app = app().ok_or(Error::new(
45+
let mtm = MainThreadMarker::new().ok_or(Error::new(
3846
ErrorKind::Other,
39-
"UIApplication is null, can't open url",
47+
"UIApplication must be retrieved on the main thread",
4048
))?;
49+
let app = sharedApplication(mtm);
4150

4251
// Create ns string class from our string
4352
let url_string = NSString::from_str(url);
@@ -50,6 +59,6 @@ pub(super) fn open_browser_internal(
5059
let options = NSDictionary::new();
5160

5261
// Open url
53-
open_url(&app, &url_object, &options, None);
62+
open_url(&app, &url_object, &options);
5463
Ok(())
5564
}

0 commit comments

Comments
 (0)