diff --git a/Cargo.lock b/Cargo.lock
index cc576e529c..308b37e542 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -6562,6 +6562,7 @@ name = "tauri-plugin-deep-link"
version = "2.4.1"
dependencies = [
"dunce",
+ "plist",
"rust-ini",
"serde",
"serde_json",
diff --git a/plugins/deep-link/Cargo.toml b/plugins/deep-link/Cargo.toml
index 7c8524bfcb..2b0cd5c522 100644
--- a/plugins/deep-link/Cargo.toml
+++ b/plugins/deep-link/Cargo.toml
@@ -27,6 +27,9 @@ serde_json = { workspace = true }
tauri-utils = { workspace = true }
tauri-plugin = { workspace = true, features = ["build"] }
+[target."cfg(target_os = \"macos\")".build-dependencies]
+plist = "1"
+
[dependencies]
serde = { workspace = true }
serde_json = { workspace = true }
diff --git a/plugins/deep-link/build.rs b/plugins/deep-link/build.rs
index 418746b234..16d2a96e57 100644
--- a/plugins/deep-link/build.rs
+++ b/plugins/deep-link/build.rs
@@ -10,50 +10,64 @@ const COMMANDS: &[&str] = &["get_current", "register", "unregister", "is_registe
// TODO: Consider using activity-alias in case users may have multiple activities in their app.
fn intent_filter(domain: &AssociatedDomain) -> String {
+ let host = domain
+ .host
+ .as_ref()
+ .map(|h| format!(r#""#))
+ .unwrap_or_default();
+
+ let auto_verify = if domain.is_app_link() {
+ r#"android:autoVerify="true" "#.to_string()
+ } else {
+ String::new()
+ };
+
format!(
- r#"
+ r#"
- {}
-
- {}
- {}
- {}
- {}
+ {schemes}
+ {host}
+ {domains}
+ {path_patterns}
+ {path_prefixes}
+ {path_suffixes}
"#,
- domain
+ schemes = domain
.scheme
.iter()
.map(|scheme| format!(r#""#))
.collect::>()
.join("\n "),
- domain.host,
- domain
+ host = host,
+ domains = domain
.path
.iter()
.map(|path| format!(r#""#))
.collect::>()
.join("\n "),
- domain
+ path_patterns = domain
.path_pattern
.iter()
.map(|pattern| format!(r#""#))
.collect::>()
.join("\n "),
- domain
+ path_prefixes = domain
.path_prefix
.iter()
.map(|prefix| format!(r#""#))
.collect::>()
.join("\n "),
- domain
+ path_suffixes = domain
.path_suffix
.iter()
.map(|suffix| format!(r#""#))
.collect::>()
.join("\n "),
)
+ .trim()
+ .to_string()
}
fn main() {
@@ -68,6 +82,16 @@ fn main() {
}
if let Some(config) = tauri_plugin::plugin_config::("deep-link") {
+ let errors: Vec = config
+ .mobile
+ .iter()
+ .filter_map(|d| d.validate().err())
+ .collect();
+
+ if !errors.is_empty() {
+ panic!("Deep link config validation failed:\n{}", errors.join("\n"));
+ }
+
tauri_plugin::mobile::update_android_manifest(
"DEEP LINK PLUGIN",
"activity",
@@ -80,20 +104,89 @@ fn main() {
)
.expect("failed to rewrite AndroidManifest.xml");
- #[cfg(target_os = "macos")]
+ #[cfg(any(target_os = "macos", target_os = "ios"))]
{
- tauri_plugin::mobile::update_entitlements(|entitlements| {
- entitlements.insert(
- "com.apple.developer.associated-domains".into(),
- config
- .mobile
- .into_iter()
- .map(|d| format!("applinks:{}", d.host).into())
- .collect::>()
- .into(),
- );
- })
- .expect("failed to update entitlements");
+ // we need to ensure that the entitlements are only
+ // generated for explicit app links and not
+ // other deep links because then they
+ // are just going to complain and not be built or signed
+ let has_app_links = config.mobile.iter().any(|d| d.is_app_link());
+
+ if !has_app_links {
+ tauri_plugin::mobile::update_entitlements(|entitlements| {
+ entitlements.remove("com.apple.developer.associated-domains");
+ })
+ .expect("failed to update entitlements");
+ } else {
+ tauri_plugin::mobile::update_entitlements(|entitlements| {
+ entitlements.insert(
+ "com.apple.developer.associated-domains".into(),
+ config
+ .mobile
+ .iter()
+ .filter(|d| d.is_app_link())
+ .filter_map(|d| d.host.as_ref())
+ .map(|host| format!("applinks:{}", host).into())
+ .collect::>()
+ .into(),
+ );
+ })
+ .expect("failed to update entitlements");
+ }
+
+ let deep_link_domains = config
+ .mobile
+ .iter()
+ .filter_map(|domain| {
+ if domain.is_app_link() {
+ return None;
+ }
+
+ Some(domain)
+ })
+ .collect::>();
+
+ if deep_link_domains.is_empty() {
+ tauri_plugin::mobile::update_info_plist(|info_plist| {
+ info_plist.remove("CFBundleURLTypes");
+ })
+ .expect("failed to update Info.plist");
+ } else {
+ tauri_plugin::mobile::update_info_plist(|info_plist| {
+ info_plist.insert(
+ "CFBundleURLTypes".into(),
+ deep_link_domains
+ .iter()
+ .map(|domain| {
+ let schemes = domain
+ .scheme
+ .iter()
+ .filter(|scheme| {
+ scheme.as_str() != "https" && scheme.as_str() != "http"
+ })
+ .collect::>();
+
+ let mut dict = plist::Dictionary::new();
+ dict.insert(
+ "CFBundleURLSchemes".into(),
+ schemes
+ .iter()
+ .map(|s| s.to_string().into())
+ .collect::>()
+ .into(),
+ );
+ dict.insert(
+ "CFBundleURLName".into(),
+ format!("{}", domain.scheme[0]).into(),
+ );
+ plist::Value::Dictionary(dict)
+ })
+ .collect::>()
+ .into(),
+ );
+ })
+ .expect("failed to update Info.plist");
+ }
}
}
}
diff --git a/plugins/deep-link/examples/app/package.json b/plugins/deep-link/examples/app/package.json
index c18b68dcbc..d983985581 100644
--- a/plugins/deep-link/examples/app/package.json
+++ b/plugins/deep-link/examples/app/package.json
@@ -11,7 +11,7 @@
},
"dependencies": {
"@tauri-apps/api": "2.8.0",
- "@tauri-apps/plugin-deep-link": "2.4.1"
+ "@tauri-apps/plugin-deep-link": "link:../.."
},
"devDependencies": {
"@tauri-apps/cli": "2.8.0",
diff --git a/plugins/deep-link/examples/app/src-tauri/gen/android/app/build.gradle.kts b/plugins/deep-link/examples/app/src-tauri/gen/android/app/build.gradle.kts
index f434bbfb0d..13ec1ffd66 100644
--- a/plugins/deep-link/examples/app/src-tauri/gen/android/app/build.gradle.kts
+++ b/plugins/deep-link/examples/app/src-tauri/gen/android/app/build.gradle.kts
@@ -14,13 +14,13 @@ val tauriProperties = Properties().apply {
}
android {
- compileSdk = 34
+ compileSdk = 36
namespace = "com.tauri.deep_link_example"
defaultConfig {
manifestPlaceholders["usesCleartextTraffic"] = "false"
applicationId = "com.tauri.deep_link_example"
minSdk = 24
- targetSdk = 34
+ targetSdk = 36
versionCode = tauriProperties.getProperty("tauri.android.versionCode", "1").toInt()
versionName = tauriProperties.getProperty("tauri.android.versionName", "1.0")
}
@@ -58,9 +58,10 @@ rust {
}
dependencies {
- implementation("androidx.webkit:webkit:1.6.1")
- implementation("androidx.appcompat:appcompat:1.6.1")
- implementation("com.google.android.material:material:1.8.0")
+ implementation("androidx.webkit:webkit:1.14.0")
+ implementation("androidx.appcompat:appcompat:1.7.1")
+ implementation("androidx.activity:activity-ktx:1.10.1")
+ implementation("com.google.android.material:material:1.12.0")
testImplementation("junit:junit:4.13.2")
androidTestImplementation("androidx.test.ext:junit:1.1.4")
androidTestImplementation("androidx.test.espresso:espresso-core:3.5.0")
diff --git a/plugins/deep-link/examples/app/src-tauri/gen/android/app/src/main/AndroidManifest.xml b/plugins/deep-link/examples/app/src-tauri/gen/android/app/src/main/AndroidManifest.xml
index 05265e325f..591f3c61e3 100644
--- a/plugins/deep-link/examples/app/src-tauri/gen/android/app/src/main/AndroidManifest.xml
+++ b/plugins/deep-link/examples/app/src-tauri/gen/android/app/src/main/AndroidManifest.xml
@@ -23,23 +23,40 @@
-
+
-
+
+
+
+
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/plugins/deep-link/examples/app/src-tauri/gen/android/app/src/main/java/com/tauri/deep_link_example/MainActivity.kt b/plugins/deep-link/examples/app/src-tauri/gen/android/app/src/main/java/com/tauri/deep_link_example/MainActivity.kt
index e13fb99560..313161c226 100644
--- a/plugins/deep-link/examples/app/src-tauri/gen/android/app/src/main/java/com/tauri/deep_link_example/MainActivity.kt
+++ b/plugins/deep-link/examples/app/src-tauri/gen/android/app/src/main/java/com/tauri/deep_link_example/MainActivity.kt
@@ -1,7 +1,11 @@
-// Copyright 2019-2023 Tauri Programme within The Commons Conservancy
-// SPDX-License-Identifier: Apache-2.0
-// SPDX-License-Identifier: MIT
-
package com.tauri.deep_link_example
-class MainActivity : TauriActivity()
+import android.os.Bundle
+import androidx.activity.enableEdgeToEdge
+
+class MainActivity : TauriActivity() {
+ override fun onCreate(savedInstanceState: Bundle?) {
+ enableEdgeToEdge()
+ super.onCreate(savedInstanceState)
+ }
+}
diff --git a/plugins/deep-link/examples/app/src-tauri/gen/android/build.gradle.kts b/plugins/deep-link/examples/app/src-tauri/gen/android/build.gradle.kts
index c5ef452a67..607240bc8f 100644
--- a/plugins/deep-link/examples/app/src-tauri/gen/android/build.gradle.kts
+++ b/plugins/deep-link/examples/app/src-tauri/gen/android/build.gradle.kts
@@ -4,7 +4,7 @@ buildscript {
mavenCentral()
}
dependencies {
- classpath("com.android.tools.build:gradle:8.5.1")
+ classpath("com.android.tools.build:gradle:8.11.0")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.25")
}
}
diff --git a/plugins/deep-link/examples/app/src-tauri/gen/android/buildSrc/build.gradle.kts b/plugins/deep-link/examples/app/src-tauri/gen/android/buildSrc/build.gradle.kts
index 39e90b0543..5c55bba71c 100644
--- a/plugins/deep-link/examples/app/src-tauri/gen/android/buildSrc/build.gradle.kts
+++ b/plugins/deep-link/examples/app/src-tauri/gen/android/buildSrc/build.gradle.kts
@@ -18,6 +18,6 @@ repositories {
dependencies {
compileOnly(gradleApi())
- implementation("com.android.tools.build:gradle:8.5.1")
+ implementation("com.android.tools.build:gradle:8.11.0")
}
diff --git a/plugins/deep-link/examples/app/src-tauri/gen/android/gradle/wrapper/gradle-wrapper.properties b/plugins/deep-link/examples/app/src-tauri/gen/android/gradle/wrapper/gradle-wrapper.properties
index 0df10d556c..c5f9a53c27 100644
--- a/plugins/deep-link/examples/app/src-tauri/gen/android/gradle/wrapper/gradle-wrapper.properties
+++ b/plugins/deep-link/examples/app/src-tauri/gen/android/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
#Tue May 10 19:22:52 CST 2022
distributionBase=GRADLE_USER_HOME
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
diff --git a/plugins/deep-link/examples/app/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/Contents.json b/plugins/deep-link/examples/app/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/Contents.json
index dd3b8bcc55..90eea7ec7e 100644
--- a/plugins/deep-link/examples/app/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/Contents.json
+++ b/plugins/deep-link/examples/app/src-tauri/gen/apple/Assets.xcassets/AppIcon.appiconset/Contents.json
@@ -1,116 +1,116 @@
{
- "images": [
+ "images" : [
{
- "size": "20x20",
- "idiom": "iphone",
- "filename": "AppIcon-20x20@2x.png",
- "scale": "2x"
+ "size" : "20x20",
+ "idiom" : "iphone",
+ "filename" : "AppIcon-20x20@2x.png",
+ "scale" : "2x"
},
{
- "size": "20x20",
- "idiom": "iphone",
- "filename": "AppIcon-20x20@3x.png",
- "scale": "3x"
+ "size" : "20x20",
+ "idiom" : "iphone",
+ "filename" : "AppIcon-20x20@3x.png",
+ "scale" : "3x"
},
{
- "size": "29x29",
- "idiom": "iphone",
- "filename": "AppIcon-29x29@2x-1.png",
- "scale": "2x"
+ "size" : "29x29",
+ "idiom" : "iphone",
+ "filename" : "AppIcon-29x29@2x-1.png",
+ "scale" : "2x"
},
{
- "size": "29x29",
- "idiom": "iphone",
- "filename": "AppIcon-29x29@3x.png",
- "scale": "3x"
+ "size" : "29x29",
+ "idiom" : "iphone",
+ "filename" : "AppIcon-29x29@3x.png",
+ "scale" : "3x"
},
{
- "size": "40x40",
- "idiom": "iphone",
- "filename": "AppIcon-40x40@2x.png",
- "scale": "2x"
+ "size" : "40x40",
+ "idiom" : "iphone",
+ "filename" : "AppIcon-40x40@2x.png",
+ "scale" : "2x"
},
{
- "size": "40x40",
- "idiom": "iphone",
- "filename": "AppIcon-40x40@3x.png",
- "scale": "3x"
+ "size" : "40x40",
+ "idiom" : "iphone",
+ "filename" : "AppIcon-40x40@3x.png",
+ "scale" : "3x"
},
{
- "size": "60x60",
- "idiom": "iphone",
- "filename": "AppIcon-60x60@2x.png",
- "scale": "2x"
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "AppIcon-60x60@2x.png",
+ "scale" : "2x"
},
{
- "size": "60x60",
- "idiom": "iphone",
- "filename": "AppIcon-60x60@3x.png",
- "scale": "3x"
+ "size" : "60x60",
+ "idiom" : "iphone",
+ "filename" : "AppIcon-60x60@3x.png",
+ "scale" : "3x"
},
{
- "size": "20x20",
- "idiom": "ipad",
- "filename": "AppIcon-20x20@1x.png",
- "scale": "1x"
+ "size" : "20x20",
+ "idiom" : "ipad",
+ "filename" : "AppIcon-20x20@1x.png",
+ "scale" : "1x"
},
{
- "size": "20x20",
- "idiom": "ipad",
- "filename": "AppIcon-20x20@2x-1.png",
- "scale": "2x"
+ "size" : "20x20",
+ "idiom" : "ipad",
+ "filename" : "AppIcon-20x20@2x-1.png",
+ "scale" : "2x"
},
{
- "size": "29x29",
- "idiom": "ipad",
- "filename": "AppIcon-29x29@1x.png",
- "scale": "1x"
+ "size" : "29x29",
+ "idiom" : "ipad",
+ "filename" : "AppIcon-29x29@1x.png",
+ "scale" : "1x"
},
{
- "size": "29x29",
- "idiom": "ipad",
- "filename": "AppIcon-29x29@2x.png",
- "scale": "2x"
+ "size" : "29x29",
+ "idiom" : "ipad",
+ "filename" : "AppIcon-29x29@2x.png",
+ "scale" : "2x"
},
{
- "size": "40x40",
- "idiom": "ipad",
- "filename": "AppIcon-40x40@1x.png",
- "scale": "1x"
+ "size" : "40x40",
+ "idiom" : "ipad",
+ "filename" : "AppIcon-40x40@1x.png",
+ "scale" : "1x"
},
{
- "size": "40x40",
- "idiom": "ipad",
- "filename": "AppIcon-40x40@2x-1.png",
- "scale": "2x"
+ "size" : "40x40",
+ "idiom" : "ipad",
+ "filename" : "AppIcon-40x40@2x-1.png",
+ "scale" : "2x"
},
{
- "size": "76x76",
- "idiom": "ipad",
- "filename": "AppIcon-76x76@1x.png",
- "scale": "1x"
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "AppIcon-76x76@1x.png",
+ "scale" : "1x"
},
{
- "size": "76x76",
- "idiom": "ipad",
- "filename": "AppIcon-76x76@2x.png",
- "scale": "2x"
+ "size" : "76x76",
+ "idiom" : "ipad",
+ "filename" : "AppIcon-76x76@2x.png",
+ "scale" : "2x"
},
{
- "size": "83.5x83.5",
- "idiom": "ipad",
- "filename": "AppIcon-83.5x83.5@2x.png",
- "scale": "2x"
+ "size" : "83.5x83.5",
+ "idiom" : "ipad",
+ "filename" : "AppIcon-83.5x83.5@2x.png",
+ "scale" : "2x"
},
{
- "size": "1024x1024",
- "idiom": "ios-marketing",
- "filename": "AppIcon-512@2x.png",
- "scale": "1x"
+ "size" : "1024x1024",
+ "idiom" : "ios-marketing",
+ "filename" : "AppIcon-512@2x.png",
+ "scale" : "1x"
}
],
- "info": {
- "version": 1,
- "author": "xcode"
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
}
-}
+}
\ No newline at end of file
diff --git a/plugins/deep-link/examples/app/src-tauri/gen/apple/Assets.xcassets/Contents.json b/plugins/deep-link/examples/app/src-tauri/gen/apple/Assets.xcassets/Contents.json
index 97a8662ebd..da4a164c91 100644
--- a/plugins/deep-link/examples/app/src-tauri/gen/apple/Assets.xcassets/Contents.json
+++ b/plugins/deep-link/examples/app/src-tauri/gen/apple/Assets.xcassets/Contents.json
@@ -1,6 +1,6 @@
{
- "info": {
- "version": 1,
- "author": "xcode"
+ "info" : {
+ "version" : 1,
+ "author" : "xcode"
}
-}
+}
\ No newline at end of file
diff --git a/plugins/deep-link/examples/app/src-tauri/gen/apple/LaunchScreen.storyboard b/plugins/deep-link/examples/app/src-tauri/gen/apple/LaunchScreen.storyboard
index dd79351ec8..81b5f90e2f 100644
--- a/plugins/deep-link/examples/app/src-tauri/gen/apple/LaunchScreen.storyboard
+++ b/plugins/deep-link/examples/app/src-tauri/gen/apple/LaunchScreen.storyboard
@@ -1,5 +1,5 @@
-
+
diff --git a/plugins/deep-link/examples/app/src-tauri/gen/apple/deep-link-example.xcodeproj/project.pbxproj b/plugins/deep-link/examples/app/src-tauri/gen/apple/deep-link-example.xcodeproj/project.pbxproj
index 450bd84706..4c01a958a8 100644
--- a/plugins/deep-link/examples/app/src-tauri/gen/apple/deep-link-example.xcodeproj/project.pbxproj
+++ b/plugins/deep-link/examples/app/src-tauri/gen/apple/deep-link-example.xcodeproj/project.pbxproj
@@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
- objectVersion = 56;
+ objectVersion = 63;
objects = {
/* Begin PBXBuildFile section */
@@ -167,6 +167,8 @@
dependencies = (
);
name = "deep-link-example_iOS";
+ packageProductDependencies = (
+ );
productName = "deep-link-example_iOS";
productReference = 1CAAFA750FD735A285DC1238 /* deep-link-example.app */;
productType = "com.apple.product-type.application";
@@ -189,6 +191,7 @@
en,
);
mainGroup = 1DC58B1705AA3ECC6B887FE7;
+ minimizedProjectReferenceProxies = 1;
projectDirPath = "";
projectRoot = "";
targets = (
@@ -227,7 +230,6 @@
outputPaths = (
"$(SRCROOT)/Externals/x86_64/${CONFIGURATION}/libapp.a",
"$(SRCROOT)/Externals/arm64/${CONFIGURATION}/libapp.a",
- "$(SRCROOT)/Externals/arm64-sim/${CONFIGURATION}/libapp.a",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
@@ -314,18 +316,13 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
- ARCHS = (
- arm64,
- "arm64-sim",
- );
+ ARCHS = arm64;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = "deep-link-example_iOS/deep-link-example_iOS.entitlements";
CODE_SIGN_IDENTITY = "iPhone Developer";
- CODE_SIGN_STYLE = Automatic;
- DEVELOPMENT_TEAM = Q93MBH6S2F;
+ DEVELOPMENT_TEAM = "Q93MBH6S2F";
ENABLE_BITCODE = NO;
- "EXCLUDED_ARCHS[sdk=iphoneos*]" = "arm64-sim x86_64";
- "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
+ "EXCLUDED_ARCHS[sdk=iphoneos*]" = x86_64;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"\".\"",
@@ -335,13 +332,6 @@
"$(inherited)",
"@executable_path/Frameworks",
);
- "LIBRARY_SEARCH_PATHS[arch=arm64-sim]" = (
- "$(inherited)",
- "$(PROJECT_DIR)/Externals/arm64-sim/$(CONFIGURATION)",
- "$(SDKROOT)/usr/lib/swift",
- "$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)",
- "$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)",
- );
"LIBRARY_SEARCH_PATHS[arch=arm64]" = (
"$(inherited)",
"$(PROJECT_DIR)/Externals/arm64/$(CONFIGURATION)",
@@ -360,7 +350,7 @@
PRODUCT_NAME = "deep-link-example";
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
- VALID_ARCHS = "arm64 arm64-sim";
+ VALID_ARCHS = arm64;
};
name = debug;
};
@@ -424,18 +414,13 @@
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
- ARCHS = (
- arm64,
- "arm64-sim",
- );
+ ARCHS = arm64;
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_ENTITLEMENTS = "deep-link-example_iOS/deep-link-example_iOS.entitlements";
CODE_SIGN_IDENTITY = "iPhone Developer";
- CODE_SIGN_STYLE = Automatic;
- DEVELOPMENT_TEAM = Q93MBH6S2F;
+ DEVELOPMENT_TEAM = "Q93MBH6S2F";
ENABLE_BITCODE = NO;
- "EXCLUDED_ARCHS[sdk=iphoneos*]" = "arm64-sim x86_64";
- "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = arm64;
+ "EXCLUDED_ARCHS[sdk=iphoneos*]" = x86_64;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"\".\"",
@@ -445,13 +430,6 @@
"$(inherited)",
"@executable_path/Frameworks",
);
- "LIBRARY_SEARCH_PATHS[arch=arm64-sim]" = (
- "$(inherited)",
- "$(PROJECT_DIR)/Externals/arm64-sim/$(CONFIGURATION)",
- "$(SDKROOT)/usr/lib/swift",
- "$(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME)",
- "$(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)",
- );
"LIBRARY_SEARCH_PATHS[arch=arm64]" = (
"$(inherited)",
"$(PROJECT_DIR)/Externals/arm64/$(CONFIGURATION)",
@@ -470,7 +448,7 @@
PRODUCT_NAME = "deep-link-example";
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
- VALID_ARCHS = "arm64 arm64-sim";
+ VALID_ARCHS = arm64;
};
name = release;
};
diff --git a/plugins/deep-link/examples/app/src-tauri/gen/apple/deep-link-example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/plugins/deep-link/examples/app/src-tauri/gen/apple/deep-link-example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
deleted file mode 100644
index 18d981003d..0000000000
--- a/plugins/deep-link/examples/app/src-tauri/gen/apple/deep-link-example.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
- IDEDidComputeMac32BitWarning
-
-
-
diff --git a/plugins/deep-link/examples/app/src-tauri/gen/apple/deep-link-example_iOS/Info.plist b/plugins/deep-link/examples/app/src-tauri/gen/apple/deep-link-example_iOS/Info.plist
index 7ce8661409..bc74b01bc2 100644
--- a/plugins/deep-link/examples/app/src-tauri/gen/apple/deep-link-example_iOS/Info.plist
+++ b/plugins/deep-link/examples/app/src-tauri/gen/apple/deep-link-example_iOS/Info.plist
@@ -15,7 +15,7 @@
CFBundlePackageType
APPL
CFBundleShortVersionString
- 0.0.0
+ 0.1.0
CFBundleVersion
0.1.0
LSRequiresIPhoneOS
@@ -40,5 +40,16 @@
UIInterfaceOrientationLandscapeLeft
UIInterfaceOrientationLandscapeRight
+ CFBundleURLTypes
+
+
+ CFBundleURLSchemes
+
+ taurideeplink
+
+ CFBundleURLName
+ taurideeplink
+
+
\ No newline at end of file
diff --git a/plugins/deep-link/examples/app/src-tauri/gen/apple/project.yml b/plugins/deep-link/examples/app/src-tauri/gen/apple/project.yml
index c924ca77bd..74d0ab4919 100644
--- a/plugins/deep-link/examples/app/src-tauri/gen/apple/project.yml
+++ b/plugins/deep-link/examples/app/src-tauri/gen/apple/project.yml
@@ -1,7 +1,3 @@
-# Copyright 2019-2023 Tauri Programme within The Commons Conservancy
-# SPDX-License-Identifier: Apache-2.0
-# SPDX-License-Identifier: MIT
-
name: deep-link-example
options:
bundleIdPrefix: com.tauri.deep-link-example
@@ -16,7 +12,6 @@ settingGroups:
base:
PRODUCT_NAME: deep-link-example
PRODUCT_BUNDLE_IDENTIFIER: com.tauri.deep-link-example
- DEVELOPMENT_TEAM: Q93MBH6S2F
targetTemplates:
app:
type: application
@@ -56,8 +51,8 @@ targets:
- UIInterfaceOrientationPortraitUpsideDown
- UIInterfaceOrientationLandscapeLeft
- UIInterfaceOrientationLandscapeRight
- CFBundleShortVersionString: 0.0.0
- CFBundleVersion: 0.0.0
+ CFBundleShortVersionString: 0.1.0
+ CFBundleVersion: '0.1.0'
entitlements:
path: deep-link-example_iOS/deep-link-example_iOS.entitlements
scheme:
@@ -67,14 +62,12 @@ targets:
settings:
base:
ENABLE_BITCODE: false
- ARCHS: [arm64, arm64-sim]
- VALID_ARCHS: arm64 arm64-sim
+ ARCHS: [arm64]
+ VALID_ARCHS: arm64
LIBRARY_SEARCH_PATHS[arch=x86_64]: $(inherited) $(PROJECT_DIR)/Externals/x86_64/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)
LIBRARY_SEARCH_PATHS[arch=arm64]: $(inherited) $(PROJECT_DIR)/Externals/arm64/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)
- LIBRARY_SEARCH_PATHS[arch=arm64-sim]: $(inherited) $(PROJECT_DIR)/Externals/arm64-sim/$(CONFIGURATION) $(SDKROOT)/usr/lib/swift $(TOOLCHAIN_DIR)/usr/lib/swift/$(PLATFORM_NAME) $(TOOLCHAIN_DIR)/usr/lib/swift-5.0/$(PLATFORM_NAME)
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES: true
- EXCLUDED_ARCHS[sdk=iphonesimulator*]: arm64
- EXCLUDED_ARCHS[sdk=iphoneos*]: arm64-sim x86_64
+ EXCLUDED_ARCHS[sdk=iphoneos*]: x86_64
groups: [app]
dependencies:
- framework: libapp.a
@@ -93,4 +86,3 @@ targets:
outputFiles:
- $(SRCROOT)/Externals/x86_64/${CONFIGURATION}/libapp.a
- $(SRCROOT)/Externals/arm64/${CONFIGURATION}/libapp.a
- - $(SRCROOT)/Externals/arm64-sim/${CONFIGURATION}/libapp.a
diff --git a/plugins/deep-link/examples/app/src-tauri/tauri.conf.json b/plugins/deep-link/examples/app/src-tauri/tauri.conf.json
index ac1c292b46..61f7394df6 100644
--- a/plugins/deep-link/examples/app/src-tauri/tauri.conf.json
+++ b/plugins/deep-link/examples/app/src-tauri/tauri.conf.json
@@ -35,6 +35,9 @@
},
{
"host": "tauri.app"
+ },
+ {
+ "scheme": ["taurideeplink"]
}
],
"desktop": {
diff --git a/plugins/deep-link/package.json b/plugins/deep-link/package.json
index d3f474e774..bceab87b6b 100644
--- a/plugins/deep-link/package.json
+++ b/plugins/deep-link/package.json
@@ -26,5 +26,8 @@
],
"dependencies": {
"@tauri-apps/api": "^2.8.0"
+ },
+ "devDependencies": {
+ "@tauri-apps/cli": "2.8.0"
}
}
diff --git a/plugins/deep-link/src/config.rs b/plugins/deep-link/src/config.rs
index 88222a2461..49de68e3de 100644
--- a/plugins/deep-link/src/config.rs
+++ b/plugins/deep-link/src/config.rs
@@ -11,10 +11,8 @@ use tauri_utils::config::DeepLinkProtocol;
pub struct AssociatedDomain {
#[serde(default = "default_schemes")]
pub scheme: Vec,
-
- #[serde(deserialize_with = "deserialize_associated_host")]
- pub host: String,
-
+ #[serde(default, deserialize_with = "deserialize_associated_host")]
+ pub host: Option, // Optional custom uri schemes dont NEED a host (may have one still), but required for https/http schemes
#[serde(default)]
pub path: Vec,
#[serde(default, alias = "path-pattern", rename = "pathPattern")]
@@ -23,6 +21,41 @@ pub struct AssociatedDomain {
pub path_prefix: Vec,
#[serde(default, alias = "path-suffix", rename = "pathSuffix")]
pub path_suffix: Vec,
+ #[serde(default, alias = "app-link", rename = "appLink")]
+ pub app_link: Option,
+}
+
+impl AssociatedDomain {
+ /// Returns true if the domain uses http or https scheme.
+ pub fn is_web_link(&self) -> bool {
+ self.scheme.iter().any(|s| s == "https" || s == "http")
+ }
+
+ /// Returns true if the domain uses http or https scheme and has proper host configuration.
+ pub fn is_app_link(&self) -> bool {
+ self.app_link
+ .unwrap_or_else(|| self.is_web_link() && self.host.is_some())
+ }
+
+ pub fn validate(&self) -> Result<(), String> {
+ // Rule 1: All web links require a host.
+ if self.is_web_link() && self.host.is_none() {
+ return Err("Web link requires a host".into());
+ }
+
+ // Rule 2: If it's an App Link, ensure http(s) and host.
+ if self.is_app_link() {
+ if !self.is_web_link() {
+ return Err("AppLink must be a valid web link (https/http + host)".into());
+ }
+ if self.scheme.iter().any(|s| s == "http") && !self.scheme.iter().any(|s| s == "https")
+ {
+ eprintln!("Warning: AppLink uses only 'http' — allowed on Android but not secure for production.");
+ }
+ }
+
+ Ok(())
+ }
}
// TODO: Consider removing this in v3
@@ -30,18 +63,19 @@ fn default_schemes() -> Vec {
vec!["https".to_string(), "http".to_string()]
}
-fn deserialize_associated_host<'de, D>(deserializer: D) -> Result
+fn deserialize_associated_host<'de, D>(deserializer: D) -> Result