Skip to content

Commit

Permalink
refactor!: use localhost for development on Android devices and emula…
Browse files Browse the repository at this point in the history
…tors or iOS simulators (tauri-apps#10437)

* feat(cli): use localhost on mobile!

* change cargo-mobile2

* use public network address on iOS device :(

* add change file

* actually breaking

* pin cargo-mobile2

* rename env var
  • Loading branch information
lucasfernog committed Aug 2, 2024
1 parent a5bfbaa commit 7ba67b4
Show file tree
Hide file tree
Showing 13 changed files with 236 additions and 339 deletions.
9 changes: 9 additions & 0 deletions .changes/dev-url-localhost-mobile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"tauri-cli": patch:breaking
"@tauri-apps/cli": patch:breaking
---

`ios dev` and `android dev` now uses localhost for the development server unless running on an iOS device,
which still requires connecting to the public network address. To conditionally check this on your frontend
framework's configuration you can check for the existence of the `TAURI_DEV_HOST`
environment variable instead of checking if the target is iOS or Android (previous recommendation).
4 changes: 2 additions & 2 deletions examples/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@
},
"dependencies": {
"@tauri-apps/api": "../../tooling/api/dist",
"@zerodevx/svelte-json-view": "1.0.9"
"@zerodevx/svelte-json-view": "1.0.9",
"internal-ip": "^7.0.0"
},
"devDependencies": {
"@iconify-json/codicon": "^1.1.49",
"@iconify-json/ph": "^1.1.13",
"@sveltejs/vite-plugin-svelte": "^3.1.1",
"@unocss/extractor-svelte": "^0.61.0",
"internal-ip": "^8.0.0",
"svelte": "^4.2.18",
"unocss": "^0.61.0",
"vite": "^5.3.2"
Expand Down
8 changes: 4 additions & 4 deletions examples/api/vite.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import Unocss from 'unocss/vite'
import { svelte } from '@sveltejs/vite-plugin-svelte'
import { internalIpV4Sync } from 'internal-ip'

const mobile = !!/android|ios/.exec(process.env.TAURI_ENV_PLATFORM)
const host = process.env.TAURI_DEV_HOST

// https://vitejs.dev/config/
export default defineConfig({
Expand All @@ -27,13 +27,13 @@ export default defineConfig({
clearScreen: false,
// tauri expects a fixed port, fail if that port is not available
server: {
host: mobile ? '0.0.0.0' : false,
host: host ? '0.0.0.0' : false,
port: 1420,
strictPort: true,
hmr: mobile
hmr: host
? {
protocol: 'ws',
host: mobile ? internalIpV4Sync() : 'localhost',
host: internalIpV4Sync(),
port: 1430
}
: undefined,
Expand Down
198 changes: 45 additions & 153 deletions examples/api/yarn.lock

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions tooling/cli/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion tooling/cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ name = "cargo-tauri"
path = "src/main.rs"

[dependencies]
cargo-mobile2 = { version = "0.12.1", default-features = false }
cargo-mobile2 = { version = "0.13", default-features = false }
jsonrpsee = { version = "0.22", features = [ "server" ] }
jsonrpsee-core = "0.22"
jsonrpsee-client-transport = { version = "0.22", features = [ "ws" ] }
Expand Down
95 changes: 7 additions & 88 deletions tooling/cli/src/dev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use tauri_utils::platform::Target;

use std::{
env::set_current_dir,
net::{IpAddr, Ipv4Addr},
net::Ipv4Addr,
process::{exit, Command, Stdio},
sync::{
atomic::{AtomicBool, Ordering},
Expand Down Expand Up @@ -75,9 +75,6 @@ pub struct Options {
/// Disable the file watcher.
#[clap(long)]
pub no_watch: bool,
/// Force prompting for an IP to use to connect to the dev server on mobile.
#[clap(long)]
pub force_ip_prompt: bool,

/// Disable the built-in dev server for static files.
#[clap(long)]
Expand Down Expand Up @@ -109,7 +106,7 @@ fn command_internal(mut options: Options) -> Result<()> {
options.target.clone(),
)?;

setup(&interface, &mut options, config, false)?;
setup(&interface, &mut options, config)?;

let exit_on_panic = options.exit_on_panic;
let no_watch = options.no_watch;
Expand All @@ -118,67 +115,10 @@ fn command_internal(mut options: Options) -> Result<()> {
})
}

pub fn local_ip_address(force: bool) -> &'static IpAddr {
static LOCAL_IP: OnceLock<IpAddr> = OnceLock::new();
LOCAL_IP.get_or_init(|| {
let prompt_for_ip = || {
let addresses: Vec<IpAddr> = local_ip_address::list_afinet_netifas()
.expect("failed to list networks")
.into_iter()
.map(|(_, ipaddr)| ipaddr)
.filter(|ipaddr| match ipaddr {
IpAddr::V4(i) => i != &Ipv4Addr::LOCALHOST,
_ => false,
})
.collect();
match addresses.len() {
0 => panic!("No external IP detected."),
1 => {
let ipaddr = addresses.first().unwrap();
*ipaddr
}
_ => {
let selected = dialoguer::Select::with_theme(&dialoguer::theme::ColorfulTheme::default())
.with_prompt(
"Failed to detect external IP, What IP should we use to access your development server?",
)
.items(&addresses)
.default(0)
.interact()
.expect("failed to select external IP");
*addresses.get(selected).unwrap()
}
}
};

let ip = if force {
prompt_for_ip()
} else {
local_ip_address::local_ip().unwrap_or_else(|_| prompt_for_ip())
};
log::info!("Using {ip} to access the development server.");
ip
})
}

pub fn setup(
interface: &AppInterface,
options: &mut Options,
config: ConfigHandle,
mobile: bool,
) -> Result<()> {
pub fn setup(interface: &AppInterface, options: &mut Options, config: ConfigHandle) -> Result<()> {
let tauri_path = tauri_dir();
set_current_dir(tauri_path).with_context(|| "failed to change current working directory")?;

let mut dev_url = config
.lock()
.unwrap()
.as_ref()
.unwrap()
.build
.dev_url
.clone();

if let Some(before_dev) = config
.lock()
.unwrap()
Expand All @@ -196,25 +136,7 @@ pub fn setup(
}
};
let cwd = script_cwd.unwrap_or_else(|| app_dir().clone());
if let Some(mut before_dev) = script {
if before_dev.contains("$HOST") {
if mobile {
let local_ip_address = local_ip_address(options.force_ip_prompt).to_string();
before_dev = before_dev.replace("$HOST", &local_ip_address);
if let Some(url) = &mut dev_url {
url.set_host(Some(&local_ip_address))?;
}
} else {
before_dev = before_dev.replace(
"$HOST",
if let Some(url) = &dev_url {
url.host_str().unwrap_or("127.0.0.1")
} else {
"127.0.0.1"
},
);
}
}
if let Some(before_dev) = script {
log::info!(action = "Running"; "BeforeDevCommand (`{}`)", before_dev);
let mut env = command_env(true);
env.extend(interface.env());
Expand Down Expand Up @@ -326,12 +248,9 @@ pub fn setup(
if let Some(FrontendDist::Directory(path)) = &frontend_dist {
if path.exists() {
let path = path.canonicalize()?;
let ip = if mobile {
*local_ip_address(options.force_ip_prompt)
} else {
Ipv4Addr::new(127, 0, 0, 1).into()
};
let server_url = builtin_dev_server::start(path, ip, options.port)?;

let server_url =
builtin_dev_server::start(path, Ipv4Addr::new(127, 0, 0, 1).into(), options.port)?;
let server_url = format!("http://{server_url}");
dev_url = Some(server_url.parse().unwrap());

Expand Down
30 changes: 17 additions & 13 deletions tooling/cli/src/mobile/android/dev.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

use super::{
configure_cargo, delete_codegen_vars, device_prompt, ensure_init, env, get_app, get_config,
inject_assets, open_and_wait, setup_dev_config, MobileTarget,
inject_assets, open_and_wait, MobileTarget,
};
use crate::{
dev::Options as DevOptions,
Expand All @@ -22,6 +22,7 @@ use clap::{ArgAction, Parser};
use anyhow::Context;
use cargo_mobile2::{
android::{
adb,
config::{Config as AndroidConfig, Metadata as AndroidMetadata},
device::Device,
env::Env,
Expand Down Expand Up @@ -63,9 +64,6 @@ pub struct Options {
pub open: bool,
/// Runs on the given device name
pub device: Option<String>,
/// Force prompting for an IP to use to connect to the dev server on mobile.
#[clap(long)]
pub force_ip_prompt: bool,
/// Disable the built-in dev server for static files.
#[clap(long)]
pub no_dev_server: bool,
Expand All @@ -87,7 +85,6 @@ impl From<Options> for DevOptions {
no_dev_server_wait: options.no_dev_server_wait,
no_dev_server: options.no_dev_server,
port: options.port,
force_ip_prompt: options.force_ip_prompt,
release_mode: options.release_mode,
}
}
Expand Down Expand Up @@ -166,7 +163,7 @@ fn run_command(options: Options, noise_level: NoiseLevel) -> Result<()> {
#[allow(clippy::too_many_arguments)]
fn run_dev(
mut interface: AppInterface,
mut options: Options,
options: Options,
mut dev_options: DevOptions,
tauri_config: ConfigHandle,
device: Option<Device>,
Expand All @@ -176,13 +173,7 @@ fn run_dev(
metadata: &AndroidMetadata,
noise_level: NoiseLevel,
) -> Result<()> {
setup_dev_config(
MobileTarget::Android,
&mut options.config,
options.force_ip_prompt,
)?;

crate::dev::setup(&interface, &mut dev_options, tauri_config.clone(), true)?;
crate::dev::setup(&interface, &mut dev_options, tauri_config.clone())?;

let interface_options = InterfaceOptions {
debug: !dev_options.release_mode,
Expand Down Expand Up @@ -216,6 +207,19 @@ fn run_dev(
},
)?;

let dev_url = tauri_config
.lock()
.unwrap()
.as_ref()
.unwrap()
.build
.dev_url
.clone();
if let Some(port) = dev_url.and_then(|url| url.port_or_known_default()) {
let forward = format!("tcp:{port}");
adb::adb(&env, ["reverse", &forward, &forward]).run()?;
}

let open = options.open;
let exit_on_panic = options.exit_on_panic;
let no_watch = options.no_watch;
Expand Down
2 changes: 1 addition & 1 deletion tooling/cli/src/mobile/android/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ use sublime_fuzzy::best_match;
use super::{
ensure_init, get_app,
init::{command as init_command, configure_cargo},
log_finished, read_options, setup_dev_config, CliOptions, OptionsHandle, Target as MobileTarget,
log_finished, read_options, CliOptions, OptionsHandle, Target as MobileTarget,
MIN_DEVICE_MATCH_SCORE,
};
use crate::{helpers::config::Config as TauriConfig, Result};
Expand Down
Loading

0 comments on commit 7ba67b4

Please sign in to comment.