diff --git a/.changes/ios-frameworks.md b/.changes/ios-frameworks.md new file mode 100644 index 000000000..fb42a61c9 --- /dev/null +++ b/.changes/ios-frameworks.md @@ -0,0 +1,7 @@ +--- +"tauri-utils": patch:feat +"@tauri-apps/cli": patch:feat +"tauri-cli": patch:feat +--- + +Added `bundle > iOS > frameworks` configuration to define a list of frameworks that are linked to the Xcode project when it is generated. diff --git a/core/tauri-config-schema/schema.json b/core/tauri-config-schema/schema.json index c20e530d1..b20ae57fe 100644 --- a/core/tauri-config-schema/schema.json +++ b/core/tauri-config-schema/schema.json @@ -2896,6 +2896,16 @@ "description": "General configuration for the iOS target.", "type": "object", "properties": { + "frameworks": { + "description": "A list of strings indicating any iOS frameworks that need to be bundled with the application.\n\n Note that you need to recreate the iOS project for the changes to be applied.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, "developmentTeam": { "description": "The development team. This value is required for iOS development because code signing is enforced.\n The `APPLE_DEVELOPMENT_TEAM` environment variable can be set to overwrite it.", "type": [ diff --git a/core/tauri-utils/src/config.rs b/core/tauri-utils/src/config.rs index 3ededf2ce..e7e4e8111 100644 --- a/core/tauri-utils/src/config.rs +++ b/core/tauri-utils/src/config.rs @@ -1889,6 +1889,10 @@ pub struct TrayIconConfig { #[cfg_attr(feature = "schema", derive(JsonSchema))] #[serde(rename_all = "camelCase", deny_unknown_fields)] pub struct IosConfig { + /// A list of strings indicating any iOS frameworks that need to be bundled with the application. + /// + /// Note that you need to recreate the iOS project for the changes to be applied. + pub frameworks: Option>, /// The development team. This value is required for iOS development because code signing is enforced. /// The `APPLE_DEVELOPMENT_TEAM` environment variable can be set to overwrite it. #[serde(alias = "development-team")] diff --git a/tooling/cli/schema.json b/tooling/cli/schema.json index c20e530d1..b20ae57fe 100644 --- a/tooling/cli/schema.json +++ b/tooling/cli/schema.json @@ -2896,6 +2896,16 @@ "description": "General configuration for the iOS target.", "type": "object", "properties": { + "frameworks": { + "description": "A list of strings indicating any iOS frameworks that need to be bundled with the application.\n\n Note that you need to recreate the iOS project for the changes to be applied.", + "type": [ + "array", + "null" + ], + "items": { + "type": "string" + } + }, "developmentTeam": { "description": "The development team. This value is required for iOS development because code signing is enforced.\n The `APPLE_DEVELOPMENT_TEAM` environment variable can be set to overwrite it.", "type": [ diff --git a/tooling/cli/src/mobile/ios/mod.rs b/tooling/cli/src/mobile/ios/mod.rs index 8c96a5ade..a921c43df 100644 --- a/tooling/cli/src/mobile/ios/mod.rs +++ b/tooling/cli/src/mobile/ios/mod.rs @@ -16,7 +16,7 @@ use cargo_mobile2::{ env::Env, opts::NoiseLevel, os, - util::prompt, + util::{prompt, relativize_path}, }; use clap::{Parser, Subcommand}; use sublime_fuzzy::best_match; @@ -27,7 +27,10 @@ use super::{ log_finished, read_options, setup_dev_config, CliOptions, OptionsHandle, Target as MobileTarget, MIN_DEVICE_MATCH_SCORE, }; -use crate::{helpers::config::Config as TauriConfig, Result}; +use crate::{ + helpers::{app_paths::tauri_dir, config::Config as TauriConfig}, + Result, +}; use std::{ env::{set_var, var_os}, @@ -104,7 +107,7 @@ pub fn command(cli: Cli, verbosity: u8) -> Result<()> { pub fn get_config( app: &App, - config: &TauriConfig, + tauri_config: &TauriConfig, features: Option<&Vec>, cli_options: &CliOptions, ) -> (AppleConfig, AppleMetadata) { @@ -119,7 +122,7 @@ pub fn get_config( let raw = RawAppleConfig { development_team: std::env::var(APPLE_DEVELOPMENT_TEAM_ENV_VAR_NAME) .ok() - .or_else(|| config.bundle.ios.development_team.clone()) + .or_else(|| tauri_config.bundle.ios.development_team.clone()) .or_else(|| { let teams = find_development_teams().unwrap_or_default(); match teams.len() { @@ -135,18 +138,52 @@ pub fn get_config( } }), ios_features: ios_options.features.clone(), - bundle_version: config.version.clone(), - bundle_version_short: config.version.clone(), + bundle_version: tauri_config.version.clone(), + bundle_version_short: tauri_config.version.clone(), ios_version: Some(TARGET_IOS_VERSION.into()), ..Default::default() }; let config = AppleConfig::from_raw(app.clone(), Some(raw)).unwrap(); + let tauri_dir = tauri_dir(); + + let mut vendor_frameworks = Vec::new(); + let mut frameworks = Vec::new(); + for framework in tauri_config + .bundle + .ios + .frameworks + .clone() + .unwrap_or_default() + { + let framework_path = PathBuf::from(&framework); + let ext = framework_path.extension().unwrap_or_default(); + if ext.is_empty() { + frameworks.push(framework); + } else if ext == "framework" { + frameworks.push( + framework_path + .file_stem() + .unwrap() + .to_string_lossy() + .to_string(), + ); + } else { + vendor_frameworks.push( + relativize_path(tauri_dir.join(framework_path), config.project_dir()) + .to_string_lossy() + .to_string(), + ); + } + } + let metadata = AppleMetadata { supported: true, ios: ApplePlatform { cargo_args: Some(ios_options.args), features: ios_options.features, + frameworks: Some(frameworks), + vendor_frameworks: Some(vendor_frameworks), ..Default::default() }, macos: Default::default(), diff --git a/tooling/cli/templates/mobile/ios/project.yml b/tooling/cli/templates/mobile/ios/project.yml index 7b535940d..893f3070a 100644 --- a/tooling/cli/templates/mobile/ios/project.yml +++ b/tooling/cli/templates/mobile/ios/project.yml @@ -97,19 +97,16 @@ targets: embed: false {{~#each ios-libraries}} - framework: {{this}} - embed: false{{/each}} - {{~#each ios-vendor-frameworks}} - - framework: {{prefix-path this}}{{/each}} - {{~#each ios-vendor-sdks}} - - sdk: {{prefix-path this}}{{/each}} + embed: false{{/each}}{{#if ios-vendor-frameworks}}{{~#each ios-vendor-frameworks}} + - framework: {{this}}{{/each}}{{/if}}{{#if ios-vendor-sdks}}{{~#each ios-vendor-sdks}} + - sdk: {{prefix-path this}}{{/each}}{{/if}} - sdk: CoreGraphics.framework - sdk: Metal.framework - sdk: MetalKit.framework - sdk: QuartzCore.framework - sdk: Security.framework - - sdk: UIKit.framework - {{~#each ios-frameworks}} - - sdk: {{this}}.framework{{/each}} + - sdk: UIKit.framework{{#if this.ios-frameworks}}{{~#each ios-frameworks}} + - sdk: {{this}}.framework{{/each}}{{/if}} - sdk: WebKit.framework preBuildScripts: {{~#each ios-pre-build-scripts}}{{#if this.path}}