mirror of
https://github.com/tauri-apps/tao.git
synced 2026-01-31 00:35:16 +01:00
feat: MacOS: add universal applink support (#1108)
by implementing `application:willContinueUserActivityWithType:` and `application:continueUserActivity:restorationHandler:`,
reusing the existing `Event::Opened { urls }` event for the user facing api.
This commit is contained in:
7
.changes/universal-app-link-support.md
Normal file
7
.changes/universal-app-link-support.md
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
"tao": patch
|
||||
---
|
||||
|
||||
feat: MacOS: add universal applink support
|
||||
by implementing `application:willContinueUserActivityWithType:` and `application:continueUserActivity:restorationHandler:`,
|
||||
reusing the existing `Event::Opened { urls }` event for the user facing api.
|
||||
16
Cargo.lock
generated
16
Cargo.lock
generated
@@ -193,6 +193,15 @@ dependencies = [
|
||||
"objc2 0.5.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block2"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1d59b4c170e16f0405a2e95aff44432a0d41aa97675f3d52623effe95792a037"
|
||||
dependencies = [
|
||||
"objc2 0.6.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "built"
|
||||
version = "0.7.5"
|
||||
@@ -1594,7 +1603,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ee638a5da3799329310ad4cfa62fbf045d5f56e3ef5ba4149e7452dcf89d5a8"
|
||||
dependencies = [
|
||||
"bitflags 2.8.0",
|
||||
"block2",
|
||||
"block2 0.5.1",
|
||||
"libc",
|
||||
"objc2 0.5.2",
|
||||
]
|
||||
@@ -1617,7 +1626,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dd0cba1276f6023976a406a14ffa85e1fdd19df6b0f737b063b95f6c8c7aadd6"
|
||||
dependencies = [
|
||||
"bitflags 2.8.0",
|
||||
"block2",
|
||||
"block2 0.5.1",
|
||||
"objc2 0.5.2",
|
||||
"objc2-foundation 0.2.2",
|
||||
]
|
||||
@@ -1629,7 +1638,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e42bee7bff906b14b167da2bac5efe6b6a07e6f7c0a21a7308d40c960242dc7a"
|
||||
dependencies = [
|
||||
"bitflags 2.8.0",
|
||||
"block2",
|
||||
"block2 0.5.1",
|
||||
"objc2 0.5.2",
|
||||
"objc2-foundation 0.2.2",
|
||||
"objc2-metal",
|
||||
@@ -2219,6 +2228,7 @@ name = "tao"
|
||||
version = "0.34.1"
|
||||
dependencies = [
|
||||
"bitflags 2.8.0",
|
||||
"block2 0.6.0",
|
||||
"core-foundation",
|
||||
"core-graphics",
|
||||
"crossbeam-channel",
|
||||
|
||||
@@ -106,6 +106,7 @@ tao-macros = { version = "0.1.0", path = "./tao-macros" }
|
||||
|
||||
[target."cfg(any(target_os = \"ios\", target_os = \"macos\"))".dependencies]
|
||||
objc2 = "0.6"
|
||||
block2 = "0.6"
|
||||
|
||||
[target."cfg(target_os = \"macos\")".dependencies]
|
||||
objc2-foundation = { version = "0.3", default-features = false, features = [
|
||||
@@ -140,6 +141,7 @@ objc2-app-kit = { version = "0.3", default-features = false, features = [
|
||||
"NSScreen",
|
||||
"NSView",
|
||||
"NSWindow",
|
||||
"NSUserActivity"
|
||||
] }
|
||||
core-foundation = "0.10"
|
||||
core-graphics = "0.24"
|
||||
|
||||
@@ -10,8 +10,12 @@ use crate::{
|
||||
},
|
||||
};
|
||||
|
||||
use objc2::runtime::{AnyClass as Class, AnyObject as Object, ClassBuilder as ClassDecl, Sel};
|
||||
use objc2_foundation::{NSArray, NSURL};
|
||||
use objc2::runtime::{
|
||||
AnyClass as Class, AnyObject as Object, Bool, ClassBuilder as ClassDecl, Sel,
|
||||
};
|
||||
use objc2_foundation::{
|
||||
NSArray, NSError, NSString, NSUserActivity, NSUserActivityTypeBrowsingWeb, NSURL,
|
||||
};
|
||||
use std::{
|
||||
cell::{RefCell, RefMut},
|
||||
ffi::{CStr, CString},
|
||||
@@ -63,6 +67,14 @@ lazy_static! {
|
||||
sel!(application:openURLs:),
|
||||
application_open_urls as extern "C" fn(_, _, _, _),
|
||||
);
|
||||
decl.add_method(
|
||||
sel!(application:willContinueUserActivityWithType:),
|
||||
application_will_continue_user_activity_with_type as extern "C" fn(_, _, _, _) -> _,
|
||||
);
|
||||
decl.add_method(
|
||||
sel!(application:continueUserActivity:restorationHandler:),
|
||||
application_continue_user_activity as extern "C" fn(_, _, _, _, _) -> _,
|
||||
);
|
||||
decl.add_method(
|
||||
sel!(applicationShouldHandleReopen:hasVisibleWindows:),
|
||||
application_should_handle_reopen as extern "C" fn(_, _, _, _) -> _,
|
||||
@@ -136,6 +148,62 @@ extern "C" fn application_open_urls(_: &Object, _: Sel, _: id, urls: &NSArray<NS
|
||||
trace!("Completed `application:openURLs:`");
|
||||
}
|
||||
|
||||
extern "C" fn application_will_continue_user_activity_with_type(
|
||||
_: &Object,
|
||||
_: Sel,
|
||||
_: id,
|
||||
user_activity_type: &NSString,
|
||||
) -> Bool {
|
||||
trace!("Trigger `application:willContinueUserActivityWithType:`");
|
||||
let result = unsafe { Bool::new(user_activity_type == NSUserActivityTypeBrowsingWeb) };
|
||||
trace!("Completed `application:willContinueUserActivityWithType:`");
|
||||
result
|
||||
}
|
||||
|
||||
extern "C" fn application_continue_user_activity(
|
||||
_: &Object,
|
||||
_: Sel,
|
||||
_: id,
|
||||
user_activity: &NSUserActivity,
|
||||
_restoration_handler: &block2::Block<dyn Fn(*mut NSError)>,
|
||||
) -> Bool {
|
||||
trace!("Trigger `application:continueUserActivity:restorationHandler:`");
|
||||
let url = unsafe {
|
||||
if user_activity
|
||||
.activityType()
|
||||
.isEqualToString(NSUserActivityTypeBrowsingWeb)
|
||||
{
|
||||
match user_activity
|
||||
.webpageURL()
|
||||
.and_then(|url| url.absoluteString())
|
||||
.and_then(|s| Some(s.to_string()))
|
||||
{
|
||||
None => {
|
||||
error!(
|
||||
"`application:continueUserActivity:restorationHandler:`: restore webbrowsing activity but url is empty"
|
||||
);
|
||||
return Bool::new(false);
|
||||
}
|
||||
Some(url_string) => match url::Url::parse(&url_string) {
|
||||
Ok(url) => url,
|
||||
Err(err) => {
|
||||
error!(
|
||||
"`application:continueUserActivity:restorationHandler:`: failed to parse url {err}"
|
||||
);
|
||||
return Bool::new(false);
|
||||
}
|
||||
},
|
||||
}
|
||||
} else {
|
||||
return Bool::new(false);
|
||||
}
|
||||
};
|
||||
|
||||
AppState::open_urls(vec![url]);
|
||||
trace!("Completed `application:continueUserActivity:restorationHandler:`");
|
||||
return Bool::new(true);
|
||||
}
|
||||
|
||||
extern "C" fn application_should_handle_reopen(
|
||||
_: &Object,
|
||||
_: Sel,
|
||||
|
||||
Reference in New Issue
Block a user