uzor-mobile 1.0.3

Mobile backend for uzor (iOS/Android)
Documentation

uzor-mobile

Mobile platform backend for uzor supporting iOS and Android.

Overview

This crate provides the mobile platform implementation for uzor, enabling touch-first applications on iOS and Android devices. It implements all platform traits with mobile-specific features like:

  • Touch Input: Multi-touch support with gesture recognition
  • Virtual Keyboard: IME integration for text input
  • Haptic Feedback: Tactile feedback for UI interactions
  • Safe Areas: Proper handling of notches, home indicators, and system bars
  • Screen Orientation: Detect and respond to orientation changes
  • Native Integration: Clipboard, URL opening, theme detection

Architecture

uzor-mobile/
├── lib.rs          # Main MobilePlatform struct + trait implementations
├── android.rs      # Android-specific backend (NDK + JNI)
├── ios.rs          # iOS-specific backend (UIKit + Objective-C)
└── common.rs       # Shared gesture recognition utilities

Platform Abstraction

The crate uses conditional compilation to provide a unified API across platforms:

#[cfg(target_os = "android")]
use android::AndroidBackend;

#[cfg(target_os = "ios")]
use ios::IosBackend;

When compiled for non-mobile platforms (e.g., during desktop development), a stub backend is used that compiles but returns placeholder values.

Usage

Basic Setup

use uzor_mobile::MobilePlatform;
use uzor_core::platform::{PlatformBackend, WindowConfig};

fn main() {
    let mut platform = MobilePlatform::new().unwrap();

    let window = platform.create_window(
        WindowConfig::new("My Mobile App")
    ).unwrap();

    // Event loop
    loop {
        while let Some(event) = platform.poll_event() {
            handle_event(event);
        }
    }
}

Touch Event Handling

use uzor_core::platform::PlatformEvent;

fn handle_event(event: PlatformEvent) {
    match event {
        PlatformEvent::TouchStart { id, x, y } => {
            println!("Touch {} started at ({}, {})", id, x, y);
        }
        PlatformEvent::TouchMove { id, x, y } => {
            println!("Touch {} moved to ({}, {})", id, x, y);
        }
        PlatformEvent::TouchEnd { id, x, y } => {
            println!("Touch {} ended at ({}, {})", id, x, y);
        }
        _ => {}
    }
}

Mobile-Specific Features

Safe Area Insets

let (top, right, bottom, left) = platform.safe_area_insets();
println!("Top inset (notch/status bar): {}", top);
println!("Bottom inset (home indicator): {}", bottom);

Haptic Feedback

use uzor_mobile::HapticStyle;

// Light tap feedback
platform.haptic_feedback(HapticStyle::Light);

// Success feedback
platform.haptic_feedback(HapticStyle::Success);

// Error feedback
platform.haptic_feedback(HapticStyle::Error);

Screen Orientation

use uzor_mobile::ScreenOrientation;

match platform.orientation() {
    ScreenOrientation::Portrait => {
        // Adjust UI for portrait
    }
    ScreenOrientation::Landscape => {
        // Adjust UI for landscape
    }
    _ => {}
}

Virtual Keyboard (IME)

use uzor_core::platform::ImeSupport;

// Show keyboard when text field is focused
platform.set_ime_allowed(true);
platform.set_ime_position(cursor_x, cursor_y);

// Hide keyboard when done
platform.set_ime_allowed(false);

Implemented Traits

PlatformBackend

Core window and event management:

  • capabilities() - Returns mobile capabilities
  • create_window() - Creates the app window (single window on mobile)
  • poll_event() - Gets platform events
  • request_redraw() - Requests screen redraw
  • window_size() - Gets screen dimensions
  • scale_factor() - Gets device pixel ratio

Clipboard

Native clipboard integration:

  • get_text() - Read clipboard text
  • set_text() - Write clipboard text

SystemIntegration

System-level operations:

  • open_url() - Opens URL in browser
  • get_system_theme() - Gets light/dark mode
  • get_scale_factor() - Gets display scaling

CursorManagement

Stub implementation (mobile devices don't have cursors):

  • set_cursor() - No-op (tracks state for compatibility)
  • set_cursor_visible() - No-op
  • set_cursor_locked() - Returns NotSupported error

ImeSupport

Virtual keyboard integration:

  • set_ime_position() - Sets keyboard position hint
  • set_ime_allowed() - Shows/hides virtual keyboard
  • set_ime_cursor_area() - Sets text field cursor area

RenderSurface

Surface for rendering:

  • raw_window_handle() - Returns None (platform-specific access needed)
  • surface_size() - Gets render surface dimensions
  • surface_scale_factor() - Gets surface scaling

Platform Capabilities

Mobile platforms have these characteristics:

PlatformCapabilities {
    has_clipboard: true,
    has_file_dialogs: true,
    has_system_theme: true,
    has_touch: true,
    has_mouse: false,          // No cursor
    has_keyboard: true,         // Virtual keyboard
    has_file_drop: false,       // Not supported
    has_cursor_management: false,
    has_ime: true,
    max_touch_points: 10,
}

Feature Flags

android

Enables Android-specific functionality:

[dependencies]
uzor-mobile = { version = "0.1.0", features = ["android"] }

Provides:

  • Android NDK integration
  • JNI bindings for Java APIs
  • Android-specific clipboard, theme detection, etc.

ios

Enables iOS-specific functionality:

[dependencies]
uzor-mobile = { version = "0.1.0", features = ["ios"] }

Provides:

  • UIKit integration
  • Objective-C bindings
  • iOS-specific clipboard, theme detection, etc.

Current Implementation Status

✅ Complete

  • Platform trait implementations
  • Gesture recognition framework
  • Feature flag structure
  • Stub backend (compiles on desktop)
  • Comprehensive tests

🚧 Stub Implementations

The following require native integration:

Android (via NDK + JNI)

  • Get screen size from Display API
  • Get density from DisplayMetrics
  • Window insets from WindowInsets API
  • Haptic feedback via Vibrator
  • Touch event processing from native activity
  • Clipboard via ClipboardManager
  • URL opening via Intent.ACTION_VIEW
  • Theme detection via Configuration
  • Virtual keyboard via InputMethodManager

iOS (via UIKit + Objective-C)

  • Get screen size from UIScreen
  • Get scale from UIScreen.scale
  • Safe area insets from UIWindow
  • Haptic feedback via UIImpactFeedbackGenerator
  • Touch event processing from UIApplication
  • Clipboard via UIPasteboard
  • URL opening via UIApplication.openURL
  • Theme detection via UITraitCollection
  • Virtual keyboard via UITextField

Next Steps

  1. Android Native Integration

    • Setup NDK activity lifecycle
    • Implement JNI wrappers for Java APIs
    • Handle touch events from native activity
  2. iOS Native Integration

    • Setup UIKit integration
    • Implement Objective-C bindings
    • Handle touch events from UIApplication
  3. Rendering Integration

    • Provide CAMetalLayer access (iOS)
    • Provide ANativeWindow access (Android)
    • Integrate with wgpu/Vello rendering

Gesture Recognition

The common module provides a gesture recognizer for high-level touch gestures:

use uzor_mobile::common::{GestureRecognizer, GestureEvent};

let mut recognizer = GestureRecognizer::new();

// Feed touch events
recognizer.touch_start(0, 100.0, 200.0);
recognizer.touch_move(0, 200.0, 210.0);
if let Some(gesture) = recognizer.touch_end(0, 200.0, 210.0) {
    match gesture {
        GestureEvent::Tap { x, y } => {
            println!("Tapped at ({}, {})", x, y);
        }
        GestureEvent::Swipe { direction, distance } => {
            println!("Swiped {:?} for {}", direction, distance);
        }
        GestureEvent::Pinch { scale, center_x, center_y } => {
            println!("Pinched with scale {}", scale);
        }
        _ => {}
    }
}

Supported gestures:

  • Tap: Quick touch and release
  • Long Press: Touch held for duration
  • Swipe: Fast directional movement
  • Pinch: Two-finger zoom in/out
  • Rotation: Two-finger rotation (TODO)

Development Notes

Compiling for Desktop

During development, you can compile on desktop platforms. The stub backend will be used:

cargo check  # Uses StubBackend
cargo test   # Tests run with stub

Compiling for Android

Requires Android NDK and cargo-mobile2:

# Install cargo-mobile2
cargo install --git https://github.com/tauri-apps/cargo-mobile2

# Build for Android
cargo mobile android build --release

Compiling for iOS

Requires Xcode and cargo-mobile2:

# Build for iOS
cargo mobile ios build --release

Testing

Run tests:

cargo test

Test with feature flags:

cargo test --features android
cargo test --features ios

Related Crates

  • uzor-core - Platform-agnostic uzor core
  • uzor-desktop - Desktop platform backend (winit)
  • uzor-web - Web platform backend (WASM)

References