Mobile Development Overview
Mobile development creates applications for smartphones and tablets. This covers cross-platform development (React Native) and native development (iOS with Swift, Android with Kotlin).
Mobile vs. Web Development
Mobile apps have unique characteristics and constraints:
| Aspect | Mobile | Web |
|---|---|---|
| Distribution | App stores (review process) | Direct (URL) |
| Updates | User must install updates | Instant deployment |
| Offline | Common, expected to work offline | Mostly online |
| Performance | Limited resources, battery concerns | More powerful hardware |
| Platform APIs | Deep OS integration | Limited browser APIs |
| Input | Touch, gestures, sensors | Mouse, keyboard |
| Screen size | Smaller, but consistent per device | Highly variable |
Cross-Platform vs. Native
React Native (Cross-Platform)
Write once in JavaScript/TypeScript, run on both iOS and Android.
Strengths:
- Code reuse: 70-90% code shared between platforms
- Faster development: Single codebase, hot reloading
- JavaScript ecosystem: npm packages, React knowledge
- Cost effective: Smaller team, faster time-to-market
Weaknesses:
- Platform limitations: Features must be supported by React Native
- Performance: Slightly slower than native for complex UIs
- Platform-specific code: Still need some native code for advanced features
- Dependency on React Native: Breaking changes, version updates
When to use: Most business apps, MVPs, smaller teams, rapid development needed.
Native iOS (Swift)
Strengths:
- Full platform access: All iOS APIs immediately available
- Best performance: Direct access to hardware, optimized for iOS
- Latest features: New iOS features available immediately
- SwiftUI: Modern declarative UI framework
When to use: iOS-specific features needed, maximum performance required, rich iOS ecosystem integration.
See iOS Guidelines.
Native Android (Kotlin)
Strengths:
- Full platform access: All Android APIs immediately available
- Best performance: Optimized for Android
- Jetpack Compose: Modern declarative UI framework
- Material Design: First-class Material Design components
When to use: Android-specific features needed, maximum performance required, deep Android integration.
See Android Guidelines.
Mobile Architecture Patterns
MVVM (Model-View-ViewModel)
Model-View-ViewModel separates UI (View) from business logic (ViewModel) from data structures (Model). This pattern is common in mobile development across platforms.
Three Layers:
-
Model: Data structures and business entities
- User, Payment, Account domain objects
- No UI logic, no platform dependencies
- Can be shared across platforms
-
ViewModel: Presentation logic and state management
- Fetches data (from API, database)
- Manages loading/error states
- Exposes data and actions to View
- Contains no UI code (no knowledge of buttons, text fields, etc.)
-
View: UI rendering
- Displays data from ViewModel
- Captures user input
- Delegates actions to ViewModel
- No business logic
Conceptual Example (User Profile):
Model:
User {
id: string
name: string
email: string
}
ViewModel (UserProfileViewModel):
State:
- user: User | null
- loading: boolean
- error: Error | null
Actions:
- loadUser(userId): Fetches user data, updates state
- updateUser(changes): Updates user via API, updates state
View (UserProfileScreen):
Observes ViewModel state
Displays:
- LoadingSpinner (if loading)
- ErrorMessage (if error)
- User name and email (if loaded)
- Update button
When button clicked:
- Calls viewModel.updateUser({ name: 'New Name' })
Benefits:
- Testability: ViewModel has no UI dependencies, easy to unit test
- Separation of concerns: UI changes don't affect business logic
- Reusability: ViewModels can be shared (e.g., between phone and tablet UIs)
- Maintainability: Clear responsibilities for each layer
Platform Implementations:
- React Native: Custom hooks as ViewModels, functional components as Views
- iOS: Combine + SwiftUI for reactive ViewModels
- Android: ViewModel class with LiveData/StateFlow, Compose/Views for UI
See framework-specific guides for implementation details.
Clean Architecture (Native Apps)
Separate concerns into layers:
┌─────────────────────────────────────┐
│ Presentation Layer │
│ (Views, ViewModels, Activities) │
└─────────────────────────────────────┘
↓
┌─────────────────────────────────────┐
│ Domain Layer │
│ (Use Cases, Business Logic) │
└─────────────────────────────────────┘
↓
┌─────────────────────────────────────┐
│ Data Layer │
│ (Repositories, Network, Database) │
└─────────────────────────────────────┘
Benefits:
- Testable (business logic independent of UI/framework)
- Maintainable (clear separation of concerns)
- Flexible (easy to change data sources or UI)
Mobile UI Patterns
Navigation
Mobile apps use stack-based navigation (screens pushed/popped). See Mobile Navigation for comprehensive navigation patterns.
Common patterns:
- Stack navigation: Push/pop screens (most common) - for drill-down hierarchies
- Tab navigation: Bottom tabs for main sections - for switching between top-level areas
- Drawer navigation: Side drawer for secondary navigation - for less frequently accessed features
- Modal: Overlay for focused tasks - for interrupting flows or creation workflows
Platform Implementations:
- React Native Navigation - React Navigation with Stack, Tab, Drawer navigators
- iOS UI - NavigationStack, TabView, Modal presentation
- Android UI - Navigation Component, BottomNavigationBar
List Virtualization
The Pattern: Only render visible items in a list to conserve memory and maintain smooth scrolling. As users scroll, off-screen items are recycled for items entering the viewport.
Why This Matters: Rendering all items in a 1,000-item list creates excessive memory pressure and slow scrolling. Virtualization keeps memory constant regardless of list size.
When to Use: Any list with more than 20-30 items should use virtualization.
Platform Implementations:
- React Native: FlatList, SectionList with infinite scroll support
- iOS: UICollectionView, List (SwiftUI) with lazy loading
- Android: RecyclerView, LazyColumn (Compose)
Pull-to-Refresh
The Pattern: Users pull down on scrollable content to trigger a refresh. Visual indicator shows refresh in progress. Content updates when refresh completes.
When to Use: Any screen displaying server data that might become stale (news feeds, transaction lists, social content).
Platform Implementations:
- React Native: RefreshControl component wrapped in ScrollView/FlatList
- iOS: UIRefreshControl, refreshable modifier (SwiftUI)
- Android: SwipeRefreshLayout, PullRefreshIndicator (Compose)
Gestures
Common Mobile Gestures:
- Tap: Single touch - primary interaction
- Long press: Touch and hold - contextual actions
- Swipe: Quick directional slide - navigation, delete actions
- Pan: Continuous drag - moving items, scrolling
- Pinch: Two-finger zoom - image zoom, map zoom
- Rotation: Two-finger rotate - less common, specialized uses
When to Use Gestures: Enhance standard interactions, not replace them. Always provide alternative interaction methods for accessibility.
Platform Implementations:
- React Native: react-native-gesture-handler for advanced gestures
- iOS: UIGestureRecognizer, SwiftUI gesture modifiers
- Android: GestureDetector, Modifier.pointerInput (Compose)
Mobile State Management
Understanding state management is critical for mobile apps where state must persist across screen changes, survive app backgrounding, and synchronize with servers. See Web State Management for universal state management patterns applicable to all frameworks.
Local State (Component Level)
What It Is: State that belongs to a single UI component. Examples: toggle states, text input values, expanded/collapsed states, selected item in a list.
When to Use: Data that doesn't need to be shared between screens or persisted beyond the component lifecycle.
Platform Approaches:
- React Native:
useState,useReducerhooks in functional components - iOS:
@Stateproperty wrapper in SwiftUI views - Android:
remember { mutableStateOf() }in Compose functions
Global State
What It Is: State shared across multiple screens or components. Examples: authenticated user, app theme, shopping cart, notification preferences.
When to Use: Data that multiple screens need access to, or state that must persist across navigation.
Patterns:
- Reactive state stores: Centralized stores with observable state (Zustand, Redux, MobX for React Native; ObservableObject for SwiftUI; StateFlow/LiveData for Android)
- Dependency injection: Pass state through DI container
- Context/Environment: Platform-specific context mechanisms
Platform Implementations:
- React State Management - Zustand, Context, React Query (applies to React Native)
- iOS UI - @State, @StateObject, @ObservedObject, @EnvironmentObject
- Android UI - State, StateFlow, ViewModel integration
Mobile Data Management
Mobile data management differs from web due to intermittent connectivity, limited storage, and battery constraints.
Offline-First Architecture
The Principle: Design apps to work offline by default. Sync with server when connected. This improves perceived performance and handles poor network conditions gracefully.
Key Patterns:
- Local database as source of truth: UI reads from local DB, syncs with server in background
- Optimistic updates: Update UI immediately, sync to server asynchronously
- Conflict resolution: Handle data conflicts when offline changes conflict with server state
- Background sync: Queue failed requests, retry when connection restored
Why This Matters: Mobile connectivity is intermittent. Users expect apps to work in subways, rural areas, and during network outages.
Platform Implementations:
- React Native Data - NetInfo, AsyncStorage, offline queue patterns
- iOS Data - Network reachability, Core Data sync
- Android Data - ConnectivityManager, Room database sync
Local Storage
Use Cases:
- Simple key-value data: User preferences, settings, authentication tokens
- Complex structured data: Local database for domain objects (users, transactions, cached API responses)
- Secure storage: Encrypted storage for sensitive data (tokens, passwords)
Storage Types:
- Key-value stores: Simple, fast, limited to primitive types and JSON-serializable objects
- Relational databases: Complex queries, relationships, migrations
- Encrypted stores: Platform keychain/keystore for sensitive data
Platform Technologies:
- React Native: AsyncStorage (key-value), Realm/SQLite (database), react-native-keychain (secure)
- iOS: UserDefaults (key-value), Core Data (database), Keychain (secure)
- Android: SharedPreferences (key-value), Room (database), EncryptedSharedPreferences/Keystore (secure)
Caching
Why Cache: Reduce network requests (save battery), faster data access, enable offline functionality.
Caching Strategies:
- Cache-first: Check cache, fetch from network only if missing
- Network-first: Fetch from network, fall back to cache on failure
- Stale-while-revalidate: Return cached data immediately, fetch fresh data in background
What to Cache: API responses, images, static assets, user-generated content.
Platform Implementations:
- React Native: React Query, SWR for API caching; FastImage for image caching
- iOS: URLCache for network responses; NSCache for in-memory caching
- Android: Retrofit with OkHttp caching; Coil/Glide for image caching
Mobile Performance
Mobile performance is critical due to device constraints. See Mobile Performance for comprehensive performance strategies.
Key Performance Concerns:
- Frame rate: Maintain 60 FPS for smooth animations and scrolling
- Memory usage: Stay within OS limits to prevent crashes
- Battery consumption: Minimize CPU usage, network requests, and background work
- App launch time: Users expect apps to be usable within 2 seconds
- Network efficiency: Reduce requests, compress data, cache aggressively
Common Optimizations:
- Minimize re-renders: Use memoization, prevent unnecessary component updates
- Virtualize lists: Render only visible items in long lists
- Optimize images: Downsample to display size, lazy load, cache
- Reduce network: Batch requests, cache responses, use compression
- Profile regularly: Use platform profiling tools to identify bottlenecks
Platform-Specific Guides:
Mobile Testing
Mobile testing requires testing on actual devices or simulators due to platform-specific behaviors, gestures, and performance characteristics.
Testing Levels
Unit Testing: Test business logic in ViewModels, use cases, and utility functions in isolation. Fast, deterministic, no UI dependencies.
Component/Widget Testing: Test individual UI components in isolation. Verify rendering logic, state changes, and user interactions without full app context.
Integration Testing: Test interactions between multiple components, navigation flows, and data layer integration.
End-to-End (E2E) Testing: Test complete user flows from app launch through multi-screen interactions. Slow but critical for catching integration issues.
Testing Tools
Cross-Platform (React Native):
- Jest + React Native Testing Library for unit/component tests
- Detox for E2E testing on iOS and Android
Native iOS:
- XCTest for unit and UI tests
- XCUITest for E2E automation
Native Android:
- JUnit + Mockito for unit tests
- Espresso for UI and E2E tests
Platform-Specific Guides:
Mobile Security
Mobile apps face unique security challenges: apps run on user-controlled devices, code can be reverse-engineered, and sensitive data persists locally.
Security Concerns
Secure Storage: Never store sensitive data (tokens, passwords, keys) in plain text. Use platform-specific encrypted storage (Keychain for iOS, Keystore for Android, react-native-keychain for React Native).
Certificate Pinning: Prevent man-in-the-middle attacks by validating server certificates against known pins. Critical for banking and financial apps.
Code Obfuscation: Protect source code from reverse engineering. Especially important for native apps where compiled binaries can be decompiled.
Input Validation: Validate and sanitize all user input. Mobile apps are just as vulnerable to injection attacks as web apps.
Biometric Authentication: Use platform biometric APIs (Face ID, Touch ID, fingerprint) for sensitive operations.
Jailbreak/Root Detection: Detect compromised devices and disable sensitive features or block app usage.
Platform-Specific Guides:
- React Native Security
- iOS Security
- Android Security
- Security Overview for general security principles
Mobile CI/CD
Mobile CI/CD is more complex than web due to platform-specific builds, code signing, and app store requirements.
CI/CD Challenges
Platform-Specific Builds: iOS requires macOS build agents and Xcode. Android requires Java/Kotlin build tools and Android SDK.
Code Signing: iOS apps require provisioning profiles and certificates. Android requires keystore files. Both must be securely managed in CI.
Build Times: Mobile builds are slower than web builds. iOS builds especially can take 10-30 minutes.
App Store Deployment: Automated deployment to TestFlight (iOS) and Play Store (Android) requires API keys and proper permissions.
CI/CD Tools
Recommended: Fastlane for automating builds, signing, and deployment across platforms. Works with any CI provider (GitLab CI, GitHub Actions, Jenkins, CircleCI).
Platform-Specific:
- iOS: Xcode Cloud for Apple-native CI/CD
- Android: Google Play deployment APIs
- React Native: CodePush for over-the-air JavaScript updates
Best Practices:
- Run tests on every commit
- Automate builds for feature branches
- Deploy to TestFlight/Play Console beta tracks on merge to main
- Use semantic versioning for releases
- Store signing credentials securely (CI secret variables)
Common Mobile Anti-Patterns
Ignoring Platform Differences
Don't try to make iOS look like Android or vice versa. Follow platform conventions.
Overusing Animations
Animations should enhance UX, not distract. Use sparingly and meaningfully.
Poor Offline Handling
Users expect mobile apps to work offline. Cache data and queue requests.
Large Bundle Sizes
Large apps take longer to download and use more storage. Optimize assets and use code splitting.
Related Guidelines
Mobile Patterns and Concepts
- Mobile Navigation - Navigation patterns (stack, tab, drawer, modal)
- Mobile Performance - Performance optimization strategies
- Frontend Overview - General frontend principles
Platform-Specific Implementation Guides
Cross-Platform (React Native):
- React Native Overview - Project setup and architecture
- React Native UI - Components and styling
- React Native Navigation - React Navigation implementation
- React Native Data - Data fetching and offline support
- React Native Security - Security best practices
- React Native Performance - Performance optimization
Native iOS (Swift):
- iOS Overview - Project setup and architecture
- iOS UI - SwiftUI development patterns
- iOS Data - Core Data and networking
- iOS Security - iOS security practices
- iOS Performance - Performance optimization
Native Android (Kotlin):
- Android Overview - Project setup and architecture
- Android UI - Jetpack Compose development
- Android Data - Room database and networking
- Android Security - Android security practices
- Android Performance - Performance optimization
Cross-Cutting Concerns
- Web State Management - State management patterns (applicable to all platforms)
- Security Overview - General security principles
Further Learning
Books:
- React Native in Action by Nader Dabit
- iOS Programming: The Big Nerd Ranch Guide
- Android Programming: The Big Nerd Ranch Guide
Online Resources: