Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Du Rust sur mobile : où en est-on ?

Du Rust sur mobile : où en est-on ?

Tauri et Dioxus sont deux frameworks pour concevoir des applications desktop en Rust. Il y a quelques semaines, ils ont annoncé le support du mobile : mais où en est-on vraiment ?

C'est ce que l'on verra dans cette présentation donnée à Android Makers by droidcon 2023

Edouard Marquez

April 29, 2023
Tweet

More Decks by Edouard Marquez

Other Decks in Programming

Transcript

  1. Android Makers 2023 Hello World :) Qui suis-je ? Edouard

    Marquez Freelance Android & Flutter @g123k @DevCafe OpenFoodFacts [email protected]
  2. Android Makers 2023 La problématique Type WebView Ionic, Cordova… Type

    Hybride React Native… Type "Natif" Flutter… Plusieurs choix sont possibles
  3. Android Makers 2023 La problématique Chromium Node.js APIs natives Initié

    par GitHub Atom Shell (2012-2013) + + Version 24 03 avril 2023 Comment ça marche ?
  4. Android Makers 2023 Desktop & cross-platform Source : https://blog.logrocket.com/advanced-electron-js-architecture/ ElectronJS

    Processus principal Processus Node Processus de rendu Module back Module front Module partagé Architecture d'ElectronJS
  5. Android Makers 2023 Desktop & cross-platform Source : https://www.levminer.com/blog/tauri-vs-electron ElectronJS

    Tauri Taille du Bundle 85 Mo 👀 Temps de démarrage 4 secondes 👀 % CPU au repos 0 % 👀 RAM au repos 120 Mo 👀 Les performances d'ElectronJS
  6. Android Makers 2023 La problématique Chromium Même rendu sur tous

    les OS Binaire très lourd Forte consommation mémoire WebView Plus de dépendance Processus plus léger Compatibilité entre les OS Et si…
  7. Android Makers 2023 Rust ? Conçu et développé par Mozilla

    Research Graydon Hoare Totalement open-source Philosophie Mozilla Excellentes performances Similaires à C/C++ "Memory Safe", sans avoir besoin de GC Vs C/C++ Syntaxe inspirée de langages connus C/C++ Récupéré par la Rust Foundation Suite aux licenciements Qu'est-ce que Rust ?
  8. Android Makers 2023 Rust ? Rust sur Android Source :

    https://security.googleblog.com/2022/12/memory-safe-languages-in-android-13.html
  9. Android Makers 2023 Rust ? Même la NSA le recommande

    ! Source : https://www.nsa.gov/Press-Room/News-Highlights/Article/Article/3215760/nsa-releases-guidance-on-how-to-protect-against-software-memory-safety-issues/
  10. Android Makers 2023 Tauri Source : https://blog.logrocket.com/advanced-electron-js-architecture/ ElectronJS Processus principal

    Processus Node Processus de rendu Module back Module front Module partagé Pour rappel, un projet ElectronJS
  11. src assets index.html main.js style.css src-tauri icons src main.rs build.rs

    Cargo.toml tauri.conf.json Arborescence d'un projet Tauri / Vanilla
  12. src assets index.html main.js style.css src-tauri icons src main.rs build.rs

    Cargo.toml tauri.conf.json Arborescence du projet Tauri / Vanilla <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <link rel="stylesheet" href="styles.css" /> <title>Tauri App</title> <script type="module" src="/main.js" defer></script> </head> <body> <div class="container"> <p>Click on the Tauri logo to learn more about the framework</p> <div class="row"> <div> <input id="greet-input" placeholder="Enter a name..." /> <button id="greet-button" type="button">Greet</button> </div> </div> <p id="greet-msg"></p> </div> </body> </html> index.html <input id="greet-input" placeholder="Enter a name..." /> <button id="greet-button" type="button">Greet</button> <p id="greet-msg"></p>
  13. src assets index.html main.js style.css src-tauri icons src main.rs build.rs

    Cargo.toml tauri.conf.json Arborescence du projet Tauri / Vanilla const { invoke } = window.__TAURI__.tauri; let greetInputEl; let greetMsgEl; async function greet() { greetMsgEl.textContent = await invoke("greet", { name: greetInputEl.value }); } window.addEventListener("DOMContentLoaded", () => { greetInputEl = document.querySelector("#greet-input"); greetMsgEl = document.querySelector("#greet-msg"); document .querySelector("#greet-button") .addEventListener("click", () => greet()); }); main.js window.addEventListener("DOMContentLoaded", () => { greetInputEl = document.querySelector("#greet-input"); greetMsgEl = document.querySelector("#greet-msg"); document .querySelector("#greet-button") .addEventListener("click", () => greet()); });
  14. src assets index.html main.js style.css src-tauri icons src main.rs build.rs

    Cargo.toml tauri.conf.json Arborescence du projet Tauri / Vanilla const { invoke } = window.__TAURI__.tauri; let greetInputEl; let greetMsgEl; async function greet() { greetMsgEl.textContent = await invoke("greet", { name: greetInputEl.value }); } window.addEventListener("DOMContentLoaded", () => { greetInputEl = document.querySelector("#greet-input"); greetMsgEl = document.querySelector("#greet-msg"); document .querySelector("#greet-button") .addEventListener("click", () => greet()); }); main.js const { invoke } = window.__TAURI__.tauri; async function greet() { greetMsgEl.textContent = await invoke("greet", { name: greetInputEl.value }); }
  15. src assets index.html main.js style.css src-tauri icons src main.rs build.rs

    Cargo.toml tauri.conf.json Arborescence du projet Tauri / Vanilla // Prevents additional console window on Windows in release, DO NOT REMOVE!! #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // Learn more about Tauri commands at https://tauri.app/v1/guides/features/command #[tauri::command] fn greet(name: &str) -> String { format!("Hello, {}! You've been greeted from Rust!", name) } fn main() { tauri::Builder::default() .invoke_handler(tauri::generate_handler![greet]) .run(tauri::generate_context!()) .expect("error while running tauri application"); } main.rs tauri::Builder::default() .invoke_handler(tauri::generate_handler![greet]) .run(tauri::generate_context!())
  16. src assets index.html main.js style.css src-tauri icons src main.rs build.rs

    Cargo.toml tauri.conf.json Arborescence du projet Tauri / Vanilla // Prevents additional console window on Windows in release, DO NOT REMOVE!! #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] // Learn more about Tauri commands at https://tauri.app/v1/guides/features/command #[tauri::command] fn greet(name: &str) -> String { format!("Hello, {}! You've been greeted from Rust!", name) } fn main() { tauri::Builder::default() .invoke_handler(tauri::generate_handler![greet]) .run(tauri::generate_context!()) .expect("error while running tauri application"); } main.rs #[tauri::command] fn greet(name: &str) -> String { format!("Hello, {}! You've been greeted from Rust!", name) }
  17. Android Makers 2023 Tauri Source : https://www.levminer.com/blog/tauri-vs-electron ElectronJS Tauri Taille

    du Bundle 85 Mo 2,5 Mo Temps de démarrage 4 secondes 2 secondes % CPU au repos 0 % 0 % RAM au repos 120 Mo 80 Mo ElectronJS VS Tauri, ça donne…
  18. src assets index.html main.js style.css src-tauri icons src lib.rs build.rs

    Cargo.toml tauri.conf.json Arborescence d'un projet Tauri 2 / Vanilla main.rs mobile.rs
  19. src assets index.html main.js style.css src-tauri icons src lib.rs build.rs

    Cargo.toml tauri.conf.json Arborescence d'un projet Tauri 2 / Vanilla main.rs mobile.rs #![cfg_attr( all(not(debug_assertions), target_os = "windows"), windows_subsystem = "windows" )] use tauriapp::AppBuilder; pub fn main() { AppBuilder::new().run(); } main.rs
  20. src assets index.html main.js style.css src-tauri icons src lib.rs build.rs

    Cargo.toml tauri.conf.json Arborescence d'un projet Tauri 2 / Vanilla main.rs mobile.rs #[tauri::mobile_entry_point] fn main() { super::AppBuilder::new().run(); } mobile.rs
  21. src assets index.html main.js style.css src-tauri icons src lib.rs build.rs

    Cargo.toml tauri.conf.json Arborescence d'un projet Tauri 2 / Vanilla main.rs mobile.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>, } #[tauri::command] fn greet(name: &str) -> String { format!("Hello, {}!", name) } 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(()) }) .invoke_handler(tauri::generate_handler![greet]) .run(tauri::generate_context!()) .expect("error while running tauri application"); } lib.rs
  22. Et le code Android / iOS ? // Initialiser le

    projet > tauri android init > tauri ios init // Lancer le projet en debug > tauri android dev > tauri ios dev shell
  23. src assets index.html main.js style.css src-tauri gen android build.rs Cargo.toml

    tauri.conf.json Arborescence d'un projet Tauri 2 / Vanilla icons src
  24. Android Makers 2023 Tauri Et les plugins ? package com.plugin.example

    import android.app.Activity import app.tauri.annotation.Command import app.tauri.annotation.TauriPlugin import app.tauri.plugin.JSObject import app.tauri.plugin.Plugin import app.tauri.plugin.Invoke @TauriPlugin class ExamplePlugin(private val activity: Activity): Plugin(activity) { @Command fun ping(invoke: Invoke) { val value = invoke.getString("value") ?: "" val ret = JSObject() ret.put("value", value) invoke.resolve(ret) MonPlugin.kt
  25. Android Makers 2023 Tauri Et les plugins ? import UIKit

    import WebKit import Tauri class ExamplePlugin: Plugin { @objc public func ping(_ invoke: Invoke) throws { let value = invoke.getString("value") invoke.resolve(["value": value as Any]) } } @_cdecl("init_plugin_example") func initPlugin(name: SRString, webview: WKWebView?) { Tauri.registerPlugin(webview: webview, name: name.toString(), plugin: ExamplePlugin()) } MonPlugin.swift
  26. Android Makers 2023 Tauri Et les plugins ? use tauri::{

    plugin::{Builder, TauriPlugin}, Manager, Runtime, }; #[cfg(target_os = "ios")] tauri::ios_plugin_binding!(init_plugin_example); pub fn init<R: Runtime>() -> TauriPlugin<R> { Builder::new("example") .setup(|app, api| { #[cfg(target_os = "android")] api.register_android_plugin("com.plugin.example", "ExamplePlugin")?; #[cfg(target_os = "ios")] api.register_ios_plugin(init_plugin_example)?; Ok(()) }) .build() main.rs
  27. Android Makers 2023 Tauri Et les plugins ? use tauri::{

    plugin::{Builder, TauriPlugin}, Manager, Runtime, }; #[cfg(target_os = "ios")] tauri::ios_plugin_binding!(init_plugin_example); pub fn init<R: Runtime>() -> TauriPlugin<R> { Builder::new("example") .setup(|app, api| { #[cfg(target_os = "android")] api.register_android_plugin("com.plugin.example", "ExamplePlugin")?; #[cfg(target_os = "ios")] api.register_ios_plugin(init_plugin_example)?; Ok(()) }) .build() main.rs #[cfg(target_os = "android")] api.register_android_plugin("com.plugin.example", "ExamplePlugin")?; #[cfg(target_os = "ios")] api.register_ios_plugin(init_plugin_example)?;
  28. Android Makers 2023 Tauri Et les plugins ? import {

    invoke } from '@tauri-apps/api/tauri' invoke('plugin:example|ping', { value: 'Tauri' }) .then(({ value }) => console.log('Response', value)) main.js
  29. Android Makers 2023 Tauri Qu'en conclure ? Les points négatifs

    Peu de doc Beaucoup de bugs Pas de deadline précise Les points positifs Meilleures performances Support de la communauté "Hype" Recommandé pour un projet desktop Attendre pour un projet mobile
  30. Android Makers 2023 Conclusion Rust au long terme Rust sur

    le desktop (Tauri) (Dioxus) Rust sur mobile L'échelle de la confiance