DEV Community

Adimac93
Adimac93

Posted on

Tauri mobile for iOS

I've been recently experimenting with Tauri alpha to try out mobile app development. By following the official guide and resolving problems, this is how I managed to set up a basic project utilising web view.

Fast forward template solution

It's highly recommended to follow this simplified guide including the project template.
You can find it here https://github.com/Adimac93/tauri-mobile-apple-ecosystem
Also, an android version (based on my template) is available here https://github.com/casey-SK/tauri-mobile-android
You may read along with this post if you are interested in particular set-up steps.

MacOS

XCode

XCode

I've tried to set up XCode both with the latest stable release (14.3.1) and the beta release (for IOS 17). However, only a stable release worked for me.

⚠️ Warning
XCode from AppStore is known for notorious problems with downloading.
Instead download it from Apple website XCode 14.3.1 download.

You will need to make sure you have command line tools installed on your machine:



$ xcode-select --install


Enter fullscreen mode Exit fullscreen mode

If you have multiple XCode CLI tool versions installed, you can set CLI version in XCode Settings... > Locations > Command Line Tools.

XCode CLI version

You should log in in XCode with your Apple ID to sign apps with a personal certificate. This will enable you to test your apps directly on your device.

Settings... > Accounts > + > Apple ID
XCode Apple ID

Rust

Next dependency is Rust which can be downloaded by following command:



$ curl --proto '=https' --tlsv1.2 https://sh.rustup.rs -sSf | sh


Enter fullscreen mode Exit fullscreen mode

If you have it already installed, make sure it's up to date:



$ rustup update


Enter fullscreen mode Exit fullscreen mode

iOS targets



$ rustup target add aarch64-apple-ios x86_64-apple-ios aarch64-apple-ios-sim


Enter fullscreen mode Exit fullscreen mode

App setup

Using Tauri scaffolding utility it's easier to set up a new project with desired frontend framework.
In this example I'll use the following options:

  • Frontend language: TypeScript
  • Package manager: pnpm
  • UI template: Svelte
  • UI flavour: TypeScript


$ cargo install create-tauri-app


Enter fullscreen mode Exit fullscreen mode


$ cargo create-tauri-app


Enter fullscreen mode Exit fullscreen mode

Console output

Install frontend dependencies:



$ cd tauri-mobile
$ pnpm add -D internal-ip
$ pnpm i


Enter fullscreen mode Exit fullscreen mode

Update tauri CLI:



$ pnpm update @tauri-apps/cli@next @tauri-apps/api@next


Enter fullscreen mode Exit fullscreen mode

and if you'd like to use CLI with cargo



$ cargo install tauri-cli --version "^2.0.0-alpha"


Enter fullscreen mode Exit fullscreen mode

Vite

Default Vite config for Svelte generated by create-tauri-app.
vite.config.ts



import { defineConfig } from "vite";
import { svelte } from "@sveltejs/vite-plugin-svelte";

// https://vitejs.dev/config/
export default defineConfig(async () => ({
  plugins: [svelte()],
  clearScreen: false,
  server: {
    port: 1420,
    strictPort: true,
  },
  envPrefix: ["VITE_", "TAURI_"],
}));



Enter fullscreen mode Exit fullscreen mode

We need to change it to the following:
vite.config.ts



import { defineConfig } from "vite";
import { svelte } from "@sveltejs/vite-plugin-svelte";
import { internalIpV4 } from 'internal-ip'

// https://vitejs.dev/config/
export default defineConfig(async () => ({
  plugins: [svelte()],
  clearScreen: false,
  server: {
    host: "0.0.0.0",
    port: 5173,
    strictPort: true,
    hmr: {
      protocol: 'ws',
      host: await internalIpV4(),
      port: 5183,
    },
  },
  envPrefix: ["VITE_", "TAURI_"],
}));



Enter fullscreen mode Exit fullscreen mode

Tauri

  1. Remove allowlist
  2. Match devPath port (same as vite.config.ts > server > port)
  3. Change bundle identifier (use only alphanumeric characters because other chars are bugged right now)

💡 Tip
A bundle ID uniquely identifies a single app throughout the system. The bundle ID string must contain only alphanumeric characters (A–Z, a–z, and 0–9), hyphens (-), and periods (.). Typically, you use a reverse-DNS format for bundle ID strings. Bundle IDs are case-insensitive.
Apple docs

src-tauri/tauri.conf.json



{
  "build": {
    "beforeDevCommand": "pnpm dev",
    "beforeBuildCommand": "pnpm build",
-   "devPath": "http://localhost:1420",
+   "devPath": "http://localhost:5173",
    "distDir": "../dist",
    "withGlobalTauri": false
  },
  "package": {
    "productName": "tauri-mobile",
    "version": "0.0.0"
  },
  "tauri": {
-   "allowlist": {
-     "all": false,
-     "shell": {
-       "all": false,
-       "open": true
-     }
-   },
    "bundle": {
      "active": true,
      "targets": "all",
-     "identifier": "com.tauri.dev",
+     "identifier": "com.<YOUR ID>.dev"
      "icon": [
        "icons/32x32.png",
        "icons/128x128.png",
        "icons/128x128@2x.png",
        "icons/icon.icns",
        "icons/icon.ico"
      ]
    },
    "security": {
      "csp": null
    },
    "windows": [
      {
        "fullscreen": false,
        "resizable": true,
        "title": "tauri-mobile",
        "width": 800,
        "height": 600
      }
    ]
  }
}


Enter fullscreen mode Exit fullscreen mode

Install iOS codegen dependencies:



$ brew install cocoapods


Enter fullscreen mode Exit fullscreen mode

Install core Cargo dependecies:



$ cargo add tauri@2.0.0-alpha.<VERSION>
$ cargo add tauri-build@2.0.0-alpha.<VERSION> --build


Enter fullscreen mode Exit fullscreen mode

If you'll get the following error:



➜ cargo add tauri@2.0.0-alpha.10

    Updating crates.io index

      Adding tauri v2.0.0-alpha.10 to dependencies.

error: unrecognized feature for crate tauri: shell-open


Enter fullscreen mode Exit fullscreen mode

all you do is
src-tauri/Cargo.toml



[package]

name = "tauri-mobile"

version = "0.0.0"

description = "A Tauri App"

authors = ["you"]

license = ""

repository = ""

edition = "2021"



# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html



[build-dependencies]

tauri-build = { version = "1.4", features = [] }



[dependencies]

- tauri = { version = "1.4", features = ["shell-open"] }

serde = { version = "1.0", features = ["derive"] }

serde_json = "1.0"



[features]

# this feature is used for production builds or when `devPath` points to the filesystem

# DO NOT REMOVE!!

- custom-protocol = ["tauri/custom-protocol"]


Enter fullscreen mode Exit fullscreen mode

after upgrading dependencies put this line back
custom-protocol = ["tauri/custom-protocol"]

Include embedded library
src-tauri/Cargo.toml



[lib]
crate-type = ["staticlib", "cdylib", "rlib"]


Enter fullscreen mode Exit fullscreen mode

Then you set up rest of the project files.
Library
src-tauri/src/lib.rs



use tauri::App;

#[cfg(mobile)]
mod mobile;
#[cfg(mobile)]
pub use mobile::*;

pub type SetupHook = Box<dyn FnOnce(&mut App) -> Result<(), Box<dyn std::error::Error>> + Send>;

#[derive(Default)]
pub struct AppBuilder {
  setup: Option<SetupHook>,
}

impl AppBuilder {
  pub fn new() -> Self {
    Self::default()
  }

  #[must_use]
  pub fn setup<F>(mut self, setup: F) -> Self
  where
    F: FnOnce(&mut App) -> Result<(), Box<dyn std::error::Error>> + Send + 'static,
  {
    self.setup.replace(Box::new(setup));
    self
  }

  pub fn run(self) {
    let setup = self.setup;
    tauri::Builder::default()
      .setup(move |app| {
        if let Some(setup) = setup {
          (setup)(app)?;
        }
        Ok(())
      })
      .run(tauri::generate_context!())
      .expect("error while running tauri application");
  }
}


Enter fullscreen mode Exit fullscreen mode

Entry point
src-tauri/src/mobile.rs



#[tauri::mobile_entry_point]
fn main() {
  super::AppBuilder::new().run();
}


Enter fullscreen mode Exit fullscreen mode

Main
src-tauri/src/main.rs



#![cfg_attr(
  all(not(debug_assertions), target_os = "windows"),
  windows_subsystem = "windows"
)]

pub fn main() {
  app::AppBuilder::new().run();
}


Enter fullscreen mode Exit fullscreen mode

That's all you need!
Now run ios dev and test your app with an emulator or connected iOS device.

Top comments (0)