diff --git a/Cargo.toml b/Cargo.toml index 4e14888..69d5f2d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -31,6 +31,10 @@ widestring = "0.5" jni = "0.19" ndk-glue = { version = ">= 0.3, <= 0.6" } +[target.'cfg(target_os = "ios")'.dependencies] +raw-window-handle = "0.5.0" +objc = "0.2.7" + [dev-dependencies] actix-web = "4" actix-files = "0.6" diff --git a/src/ios.rs b/src/ios.rs new file mode 100644 index 0000000..d9e6353 --- /dev/null +++ b/src/ios.rs @@ -0,0 +1,38 @@ +use crate::{Browser, BrowserOptions, Error, ErrorKind, Result}; +use objc::{class, msg_send, runtime::Object, sel, sel_impl}; + +/// Deal with opening of browsers on iOS +#[inline] +pub fn open_browser_internal( + _browser: Browser, + url: &str, + _options: &BrowserOptions, +) -> Result<()> { + // always return true for a dry run + if _options.dry_run { + return Ok(()); + } + let url_s: String = match url::Url::parse(url) { + Ok(u) => u.as_str().into(), + Err(_) => url.into(), + }; + unsafe { + let app: *mut Object = msg_send![class!(UIApplication), sharedApplication]; + if app.is_null() { + return Err(Error::new( + ErrorKind::Other, + "UIApplication is null, can't open url", + )); + } + let url_cstr = std::ffi::CString::new(url_s).unwrap(); + // Create ns string class from our string + let url_string: *mut Object = msg_send![class!(NSString), stringWithUTF8String: url_cstr]; + // Create NSURL object with given string + let url_object: *mut Object = msg_send![class!(NSURL), URLWithString: url_string]; + // No completion handler + let null_ptr = 0 as *mut Object; + // Open url + let () = msg_send![app, openURL: url_object options: {} completionHandler: null_ptr]; + Ok(()) + } +} diff --git a/src/lib.rs b/src/lib.rs index e57d566..62cd527 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -22,13 +22,14 @@ //! | android | ✅ | default only | ✅ | //! | wasm | ✅ | default only | ✅ | //! | haiku | ✅ (experimental) | default only | ❌ | -//! | ios | ❌ | unsupported | ❌ | +//! | ios | ✅ | default only | ❌ | //! //! ## Consistent Behaviour //! `webbrowser` defines consistent behaviour on all platforms as follows: //! * **Non-Blocking** for GUI based browsers (e.g. Firefox, Chrome etc.), while **Blocking** for text based browser (e.g. lynx etc.) //! * **Suppressed output** by default for GUI based browsers, so that their stdout/stderr don't pollute the main program's output. This can be overridden by `webbrowser::open_browser_with_options`. +#[cfg_attr(target_os = "ios", path = "ios.rs")] #[cfg_attr(target_os = "macos", path = "macos.rs")] #[cfg_attr(target_os = "android", path = "android.rs")] #[cfg_attr(target_arch = "wasm32", path = "wasm.rs")] @@ -54,9 +55,12 @@ mod os; target_os = "netbsd", target_os = "openbsd", target_os = "haiku", + target_os = "ios", target_arch = "wasm32" )))] -compile_error!("Only Windows, Mac OS, Linux, *BSD and Haiku and Wasm32 are currently supported"); +compile_error!( + "Only Windows, Mac OS, iOS, Linux, *BSD and Haiku and Wasm32 are currently supported" +); use std::default::Default; use std::io::{Error, ErrorKind, Result};