Mobile Development
Skelenote uses Tauri 2.0's mobile support to build native iOS and Android apps from the same codebase as the desktop app. This guide covers setup, development, and mobile-specific patterns.
Overview
The mobile apps share the same React frontend and Rust backend as the desktop app, with platform-specific native capabilities accessed through Tauri plugins and custom commands.
Mobile code locations:
src-tauri/gen/apple/
iOS/macOS Xcode project
src-tauri/gen/android/
Android Gradle project
src/components/mobile/
Mobile-specific React components
src/hooks/use*.ts
Platform-aware hooks (many are mobile-specific)
Prerequisites
iOS Development
macOS - iOS development requires macOS
Xcode 15+ - Install from the App Store
Xcode Command Line Tools:
xcode-select --installCocoaPods (for iOS dependencies):
sudo gem install cocoapodsiOS Simulator - Included with Xcode (download additional simulators in Xcode > Settings > Platforms)
Android Development
Android Studio - Download from developer.android.com
Android SDK - Install via Android Studio (SDK Manager)
Android NDK - Required for Rust compilation
Open Android Studio > SDK Manager > SDK Tools
Check "NDK (Side by side)" and install
Environment variables - Add to your shell profile (
.zshrcor.bashrc):Java 17 - Required by Gradle:
Rust Targets
Install the mobile Rust targets:
iOS Development Setup
Initial Setup
Initialize iOS project (if not already done):
Install CocoaPods dependencies:
Open in Xcode (optional, for signing and capabilities):
Running on iOS Simulator
This will:
Build the Rust library for the iOS simulator
Build the frontend
Launch the iOS simulator
Install and run the app
Specify a simulator:
List available simulators:
Running on Physical iOS Device
Connect your device via USB
Open
src-tauri/gen/apple/skelenote.xcworkspacein XcodeSelect your team in Signing & Capabilities
Select your device as the run target
Run from Xcode (Cmd+R) or:
Building for Release
Output: src-tauri/gen/apple/build/skelenote_iOS.xcarchive
For App Store distribution, archive and export from Xcode.
Android Development Setup
Initial Setup
Initialize Android project (if not already done):
Verify environment:
Check that Android SDK and NDK are detected.
Running on Android Emulator
Create an AVD (Android Virtual Device) in Android Studio:
Open AVD Manager (Tools > Device Manager)
Create a device with API 24+ (Android 7.0+)
Start the emulator and run:
Specify an emulator:
Running on Physical Android Device
Enable Developer Options on your device
Enable USB Debugging
Connect via USB and authorize the connection
Run:
Building for Release
Output: src-tauri/gen/android/app/build/outputs/apk/
For Play Store distribution, generate a signed AAB:
Platform Detection Patterns
Use the usePlatform() hook to detect the current platform and adapt the UI:
Conditional Rendering
Safe Area Handling
Mobile devices have safe area insets for notches, home indicators, and status bars. The usePlatform() hook provides these values:
CSS Environment Variables
For CSS-based handling, use the env() function:
Default Values
Platform
safeAreaTop
safeAreaBottom
iOS (iPhone with notch)
47px
34px
Android
24px
0px
Desktop
0px
0px
The hook reads actual values from CSS env() on mount and uses these defaults as fallbacks.
Mobile Hooks Reference
usePlatform()
usePlatform()Platform detection and safe area insets.
useHaptics()
useHaptics()Haptic feedback for tactile responses on mobile.
Tauri commands called:
haptic_impacthaptic_notificationhaptic_selection
useBiometric()
useBiometric()Biometric authentication (Face ID, Touch ID, fingerprint).
Plugin used: @tauri-apps/plugin-biometric
useQRScanner()
useQRScanner()QR code scanning for device pairing.
Plugin used: @tauri-apps/plugin-barcode-scanner
useNotifications()
useNotifications()Push notifications for task reminders.
Plugin used: @tauri-apps/plugin-notification
useAppIcon()
useAppIcon()Dynamic app icon switching (iOS, Android, macOS).
Platform behavior:
iOS: Shows system confirmation prompt, persists across launches
Android: Uses activity aliases, persists across launches
macOS: Changes dock icon for current session only
Tauri commands called:
is_icon_switching_supportedget_available_iconsset_app_icon
useShareHandler()
useShareHandler()Handle content shared from other apps.
Behavior:
Checks for pending shares on mount
Checks when app returns from background
Creates Link objects for URLs, Note objects for text
Shows toast notification on success
Native implementation:
iOS: Share Extension in
src-tauri/gen/apple/SkelenoteShare/Android: Share Intent handler in
ShareReceiverActivity.kt
useBackgroundTask()
useBackgroundTask()iOS background execution for completing sync.
Note: iOS grants approximately 30 seconds for background execution.
Tauri commands called:
begin_background_taskend_background_task
useDeepLinks()
useDeepLinks()Handle skelenote:// URLs for navigation.
Supported URL formats:
skelenote://task/{id}- Navigate to taskskelenote://note/{id}- Navigate to noteskelenote://object/{id}- Navigate to any objectskelenote://inbox- Navigate to inboxskelenote://tasks- Navigate to tasks viewskelenote://daily- Navigate to daily notes
Plugin used: @tauri-apps/plugin-deep-link
Mobile Components
Mobile-specific React components are in src/components/mobile/:
Primitives
Basic building blocks for mobile UI:
SwipeableRow
Row with swipe-to-reveal actions
BottomSheet
iOS-style bottom sheet modal
ActionSheet
iOS-style action menu
FAB
Floating action button
PullToRefresh
Pull-to-refresh wrapper
CollapsibleSection
Expandable/collapsible section
AnimatedCheckbox
Animated task checkbox
SelectionToolbar
Multi-select action toolbar
MobileViewHeader
Standard mobile view header
MobileSyncIndicator
Sync status indicator
PropertyChip
Compact property display
EmptyState
Empty state placeholder
Views
Full-screen mobile views:
MobileInboxView
Inbox with swipe actions
MobileTasksView
Tasks with filters and quick add
MobileDailyNotesView
Daily notes timeline
MobileObjectDetailView
Object detail/editor
MobileSearchModal
Full-screen search
MobileSettingsView
Settings with nested sheets
MobileBrowseView
Browse by type/project/area
MobileArchiveView
Archived objects
LockScreen
Biometric lock screen
Sheets
Bottom sheet modals for actions and pickers:
QuickAddTaskSheet
Quick task creation
QuickCaptureSheet
Quick capture to inbox
PropertyEditorSheet
Edit object properties
StatusPickerSheet
Task status picker
PriorityPickerSheet
Priority picker
DueDateSheet
Date picker with presets
ReminderSheet
Reminder time picker
RecurrenceSheet
Recurrence pattern editor
TagPickerSheet
Tag multi-select
ProjectPickerSheet
Project selector
AreaPickerSheet
Area selector
TemplatePickerSheet
Template selector
BulkActionsSheet
Multi-select actions
AccountSettingsSheet
Account settings
SyncSettingsSheet
Sync configuration
DeviceManagerSheet
Device management
Debugging on Mobile
iOS Debugging
Safari Web Inspector (recommended):
Enable Web Inspector on device: Settings > Safari > Advanced > Web Inspector
Open Safari on Mac
Develop menu > [Device Name] > [App WebView]
Full DevTools access (Console, Network, Elements, etc.)
Xcode Console:
Run from Xcode
View > Debug Area > Activate Console
See
println!output from Rust andconsole.logfrom JavaScript
Logging:
Android Debugging
Chrome DevTools:
Enable USB debugging on device
Open
chrome://inspectin ChromeFind your app's WebView and click "inspect"
Full DevTools access
Android Studio Logcat:
Run from Android Studio or connect device
View > Tool Windows > Logcat
Filter by app package name
ADB Logcat (command line):
Common Debugging Tips
Check platform detection: Log
usePlatform()values on mountVerify Tauri commands: Wrap in try/catch and log errors
Test on real devices: Simulators may behave differently
Check permissions: Camera, biometric, notifications need explicit permission
Building for Release
iOS Release Build
Output: src-tauri/gen/apple/build/skelenote_iOS.xcarchive
For App Store submission:
Open the xcarchive in Xcode Organizer
Validate App
Distribute App > App Store Connect
Android Release Build
Signing the release:
Create a keystore:
Configure signing in
src-tauri/gen/android/app/build.gradle.kts:
Output: src-tauri/gen/android/app/build/outputs/
Configuration Files
iOS (src-tauri/tauri.conf.json):
Android (src-tauri/gen/android/app/build.gradle.kts):
minSdk,targetSdk,compileSdkSigning configuration
ProGuard rules
Troubleshooting
iOS Issues
"Could not find a development team"
Open the Xcode project and select a team in Signing & Capabilities
CocoaPods errors
Simulator not starting
Android Issues
"NDK not found"
Install NDK via Android Studio SDK Manager
Set
NDK_HOMEenvironment variable
"JAVA_HOME is not set"
Emulator performance
Enable hardware acceleration (HAXM on Intel, Hypervisor on ARM)
Use x86_64 system image for better performance
General Issues
"Command not found: tauri"
Rust target not installed
Build cache issues
Last updated