From 56dd885ea613bd66628ca8c1f7da9a45b5f9dd61 Mon Sep 17 00:00:00 2001 From: "Campione.Dev" Date: Fri, 30 Aug 2024 18:26:45 +0200 Subject: [PATCH 1/2] feat(iOS): added custom URL schemes handling in the `AppDelegate` class Until now, only ["associated domains"](https://developer.apple.com/documentation/xcode/supporting-associated-domains) were handled, using the `application_continue` function, that implements [this Swift method from the `UIApplicationDelegate` class](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623072-application). For [custom URL schemes](https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app), I added a new `application_open_url` function that matches the signature of [this other Swift method](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623112-application). Most of the code of the pre-existing `application_continue` has been moved into a separate `handle_deep_link` function so the new `application_open_url` can call it as well. I believe using the same `Event::Opened` event is appropriate in both situations. Since the scheme is part of the URL, a listener can differentiate between them if needed. **Tauri:** since we are emitting the same `Event::Opened` event, this change works automatically with the ["Deep Linking" plugin](https://v2.tauri.app/plugin/deep-linking/) without further modifications. Custom URL schemes in mobile apps are essential, for example, when dealing with OAuth redirect URLs. --- .changes/ios-custom-url-schemes.md | 35 ++++++++++++++++++++ src/platform_impl/ios/view.rs | 51 +++++++++++++++++++++++------- 2 files changed, 74 insertions(+), 12 deletions(-) create mode 100644 .changes/ios-custom-url-schemes.md diff --git a/.changes/ios-custom-url-schemes.md b/.changes/ios-custom-url-schemes.md new file mode 100644 index 000000000..7353ce416 --- /dev/null +++ b/.changes/ios-custom-url-schemes.md @@ -0,0 +1,35 @@ +--- +"tao": patch +--- + +# iOS: added custom URL schemes handling in the AppDelegate class + +Until now, only ["associated +domains"](https://developer.apple.com/documentation/xcode/supporting-associated-domains) +were handled, using the `application_continue` function, that implements [this +Swift method from the `UIApplicationDelegate` +class](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623072-application). + +For [custom URL +schemes](https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app), +I added a new `application_open_url` function that matches the signature of +[this other Swift +method](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623112-application). + +Most of the code of the pre-existing `application_continue` has been moved +into a separate `handle_deep_link` function so the new `application_open_url` +can call it as well. + +I believe using the same `Event::Opened` event is appropriate in both +situations. Since the scheme is part of the URL, a listener can differentiate +between them if needed. + +## Tauri: + +Since we are emitting the same `Event::Opened` event, this change +works automatically with the ["Deep Linking" +plugin](https://v2.tauri.app/plugin/deep-linking/) without further +modifications. + +Custom URL schemes in mobile apps are essential, for example, +when dealing with OAuth redirect URLs. diff --git a/src/platform_impl/ios/view.rs b/src/platform_impl/ios/view.rs index 18b6025b8..bed79b856 100644 --- a/src/platform_impl/ios/view.rs +++ b/src/platform_impl/ios/view.rs @@ -555,7 +555,40 @@ pub fn create_delegate_class() { YES } + fn handle_deep_link(url: id) { + unsafe { + let absolute_url: id = msg_send![url, absoluteString]; + let bytes = { + let bytes: *const c_char = msg_send![absolute_url, UTF8String]; + bytes as *const u8 + }; + + // 4 represents utf8 encoding + let len = msg_send![absolute_url, lengthOfBytesUsingEncoding: 4]; + let bytes = std::slice::from_raw_parts(bytes, len); + + let url = url::Url::parse(std::str::from_utf8(bytes).unwrap()).unwrap(); + + app_state::handle_nonuser_event(EventWrapper::StaticEvent(Event::Opened { urls: vec![url] })); + } + } + + // custom URL schemes + // https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app + extern "C" fn application_open_url( + _self: &mut Object, + _cmd: Sel, + _app: id, + url: id, + _options: id, + ) -> BOOL { + handle_deep_link(url); + + YES + } + // universal links + // https://developer.apple.com/documentation/xcode/supporting-universal-links-in-your-app extern "C" fn application_continue( _: &mut Object, _: Sel, @@ -568,19 +601,8 @@ pub fn create_delegate_class() { if webpage_url == nil { return NO; } - let absolute_url: id = msg_send![webpage_url, absoluteString]; - let bytes = { - let bytes: *const c_char = msg_send![absolute_url, UTF8String]; - bytes as *const u8 - }; - // 4 represents utf8 encoding - let len = msg_send![absolute_url, lengthOfBytesUsingEncoding: 4]; - let bytes = std::slice::from_raw_parts(bytes, len); - - let url = url::Url::parse(std::str::from_utf8(bytes).unwrap()).unwrap(); - - app_state::handle_nonuser_event(EventWrapper::StaticEvent(Event::Opened { urls: vec![url] })); + handle_deep_link(webpage_url); YES } @@ -631,6 +653,11 @@ pub fn create_delegate_class() { did_finish_launching as extern "C" fn(&mut Object, Sel, id, id) -> BOOL, ); + decl.add_method( + sel!(application:openURL:options:), + application_open_url as extern "C" fn(&mut Object, Sel, id, id, id) -> BOOL, + ); + decl.add_method( sel!(application:continueUserActivity:restorationHandler:), application_continue as extern "C" fn(&mut Object, Sel, id, id, id) -> BOOL, From 373e133c62c67656529806e382a366b28abc2ae8 Mon Sep 17 00:00:00 2001 From: "Campione.Dev" Date: Mon, 2 Sep 2024 13:18:15 +0200 Subject: [PATCH 2/2] Update .changes/ios-custom-url-schemes.md Co-authored-by: Jason Tsai --- .changes/ios-custom-url-schemes.md | 32 +----------------------------- 1 file changed, 1 insertion(+), 31 deletions(-) diff --git a/.changes/ios-custom-url-schemes.md b/.changes/ios-custom-url-schemes.md index 7353ce416..810da0f6f 100644 --- a/.changes/ios-custom-url-schemes.md +++ b/.changes/ios-custom-url-schemes.md @@ -2,34 +2,4 @@ "tao": patch --- -# iOS: added custom URL schemes handling in the AppDelegate class - -Until now, only ["associated -domains"](https://developer.apple.com/documentation/xcode/supporting-associated-domains) -were handled, using the `application_continue` function, that implements [this -Swift method from the `UIApplicationDelegate` -class](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623072-application). - -For [custom URL -schemes](https://developer.apple.com/documentation/xcode/defining-a-custom-url-scheme-for-your-app), -I added a new `application_open_url` function that matches the signature of -[this other Swift -method](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623112-application). - -Most of the code of the pre-existing `application_continue` has been moved -into a separate `handle_deep_link` function so the new `application_open_url` -can call it as well. - -I believe using the same `Event::Opened` event is appropriate in both -situations. Since the scheme is part of the URL, a listener can differentiate -between them if needed. - -## Tauri: - -Since we are emitting the same `Event::Opened` event, this change -works automatically with the ["Deep Linking" -plugin](https://v2.tauri.app/plugin/deep-linking/) without further -modifications. - -Custom URL schemes in mobile apps are essential, for example, -when dealing with OAuth redirect URLs. +On iOS, implement `application:openURL:options:` to handle custom URL schemes.