Senior Mobile Developer
Expert mobile application development across iOS, Android, React Native, and Flutter.
Keywords
mobile, ios, android, react-native, flutter, swift, kotlin, swiftui,
jetpack-compose, expo-router, zustand, app-store, performance, offline-first
Quick Start
python scripts/mobile_scaffold.py --platform react-native --name MyApp
python scripts/build.py --platform ios --env production
python scripts/store_metadata.py --screenshots ./screenshots
python scripts/profile.py --platform android --output report.html
Tools
| Script |
Purpose |
scripts/mobile_scaffold.py |
Scaffold project for react-native, ios, android, or flutter |
scripts/build.py |
Build automation with environment and platform flags |
scripts/store_metadata.py |
Generate App Store / Play Store listing metadata |
scripts/profile.py |
Profile rendering, memory, and startup performance |
Platform Decision Matrix
| Aspect |
Native iOS |
Native Android |
React Native |
Flutter |
| Language |
Swift |
Kotlin |
TypeScript |
Dart |
| UI Framework |
SwiftUI/UIKit |
Compose/XML |
React |
Widgets |
| Performance |
Best |
Best |
Good |
Very Good |
| Code Sharing |
None |
None |
~80% |
~95% |
| Best For |
iOS-only, hardware-heavy |
Android-only, hardware-heavy |
Web team, shared logic |
Maximum code sharing |
Workflow 1: Scaffold a React Native App (Expo Router)
- Generate project --
python scripts/mobile_scaffold.py --platform react-native --name MyApp
- Verify directory structure matches this layout:
src/
βββ app/ # Expo Router file-based routes
β βββ (tabs)/ # Tab navigation group
β βββ auth/ # Auth screens
β βββ _layout.tsx # Root layout
βββ components/
β βββ ui/ # Reusable primitives (Button, Input, Card)
β βββ features/ # Domain components (ProductCard, UserAvatar)
βββ hooks/ # Custom hooks (useAuth, useApi)
βββ services/ # API clients and storage
βββ stores/ # Zustand state stores
βββ utils/ # Helpers
- Configure navigation in
app/_layout.tsx with Stack and Tabs.
- Set up state management with Zustand + AsyncStorage persistence.
- Validate -- Run the app on both iOS simulator and Android emulator. Confirm navigation and state persistence work.
Workflow 2: Build a SwiftUI Feature (iOS)
- Create the View using
NavigationStack, @StateObject for ViewModel binding, and .task for async data loading.
- Create the ViewModel as
@MainActor class with @Published properties. Inject services via protocol for testability.
- Wire data flow: View observes ViewModel -> ViewModel calls Service -> Service returns data -> ViewModel updates
@Published -> View re-renders.
- Add search/refresh:
.searchable(text:) for filtering, .refreshable for pull-to-refresh.
- Validate -- Run in Xcode previews first, then simulator. Confirm async loading, error states, and empty states all render correctly.
Example: SwiftUI ViewModel Pattern
@MainActor
class ProductListViewModel: ObservableObject {
@Published private(set) var products: [Product] = []
@Published private(set) var isLoading = false
@Published private(set) var error: Error?
private let service: ProductServiceProtocol
init(service: ProductServiceProtocol = ProductService()) {
self.service = service
}
func loadProducts() async {
isLoading = true
error = nil
do {
products = try await service.fetchProducts()
} catch {
self.error = error
}
isLoading = false
}
}
Workflow 3: Build a Jetpack Compose Feature (Android)
- Create the Composable screen with
Scaffold, TopAppBar, and state collection via collectAsStateWithLifecycle().
- Handle UI states with a sealed interface:
Loading, Success<T>, Error.
- Create the ViewModel with
@HiltViewModel, MutableStateFlow, and repository injection.
- Build list UI using
LazyColumn with key parameter for stable identity and Arrangement.spacedBy() for spacing.
- Validate -- Run on emulator. Confirm state transitions (loading -> success, loading -> error -> retry) work correctly.
Example: Compose UiState Pattern
sealed interface UiState<out T> {
data object Loading : UiState<Nothing>
data class Success<T>(val data: T) : UiState<T>
data class Error(val message: String) : UiState<Nothing>
}
@HiltViewModel
class ProductListViewModel @Inject constructor(
private val repository: ProductRepository
) : ViewModel() {
private val _uiState = MutableStateFlow<UiState<List<Product>>>(UiState.Loading)
val uiState: StateFlow<UiState<List<Product>>> = _uiState.asStateFlow()
fun loadProducts() {
viewModelScope.launch {
_uiState.value = UiState.Loading
repository.getProducts()
.catch { e -> _uiState.value = UiState.Error(e.message ?: "Unknown error") }
.collect { products -> _uiState.value = UiState.Success(products) }
}
}
}
Workflow 4: Optimize Mobile Performance
- Profile --
python scripts/profile.py --platform <ios|android> --output report.html
- Apply React Native optimizations:
- Use
FlatList with keyExtractor, initialNumToRender=10, windowSize=5, removeClippedSubviews=true
- Memoize components with
React.memo and handlers with useCallback
- Supply
getItemLayout for fixed-height rows to skip measurement
- Apply native iOS optimizations:
- Implement
prefetchItemsAt for image pre-loading in collection views
- Apply native Android optimizations:
- Set
setHasFixedSize(true) and setItemViewCacheSize(20) on RecyclerViews
- Validate -- Re-run profiler and confirm frame drops reduced and startup time improved.
Workflow 5: Submit to App Store / Play Store
- Generate metadata --
python scripts/store_metadata.py --screenshots ./screenshots
- Build release --
python scripts/build.py --platform ios --env production
- Review the generated listing (title, description, keywords, screenshots).
- Upload via Xcode (iOS) or Play Console (Android).
- Validate -- Monitor review status and address any rejection feedback.
Reference Materials
Troubleshooting
| Problem |
Cause |
Solution |
| App crashes on launch after adding a new dependency |
Incompatible native module version or missing pod install / gradle sync |
Run npx pod-install (iOS) or cd android && ./gradlew clean (Android). Verify dependency version compatibility in the changelog. |
| FlatList renders blank or flickers |
Missing keyExtractor, unstable keys, or inline renderItem causing full re-renders |
Add a stable keyExtractor, wrap renderItem in useCallback, and supply getItemLayout for fixed-height rows. |
| iOS build fails with "signing" error |
Provisioning profile mismatch or expired certificate |
Open Xcode > Signing & Capabilities, select the correct team and profile. Run security find-identity -v -p codesigning to verify certificates. |
| Android build OOM during dexing |
Insufficient JVM heap for large projects |
Add org.gradle.jvmargs=-Xmx4096m to gradle.properties. Enable dexOptions { javaMaxHeapSize "4g" } in build.gradle. |
| App Store rejection for missing privacy manifest |
Apple requires PrivacyInfo.xcprivacy for apps using required reason APIs (UserDefaults, file timestamp, etc.) |
Add a PrivacyInfo.xcprivacy file declaring each required reason API. Run store_metadata_generator.py to review privacy label guidance. |
| Slow cold start time (>3 seconds) |
Too many synchronous operations on the main thread at launch, large bundle size, or unoptimized images |
Defer non-critical initialization, lazy-load modules, compress images, and use app_performance_analyzer.py to identify bottlenecks. |
| Hot reload / fast refresh stops working |
Syntax error in a module boundary, anonymous default export, or class component state |
Check terminal for error messages, ensure named exports, and restart the Metro bundler or Flutter daemon with a cache clear. |
Success Criteria
- App startup time under 2 seconds on cold launch (measured on mid-range devices, both iOS and Android).
- Crash-free rate above 99.5% across all supported OS versions, tracked via Crashlytics or Sentry.
- Frame rendering at 60 fps (16ms per frame) for scrolling lists and animations, with zero jank frames during typical user flows.
- Bundle size under 50 MB for the initial download (excluding on-demand resources), verified before each release.
- Performance analyzer score of 75+ (Grade B or above) when running
app_performance_analyzer.py against the project.
- Zero critical issues and fewer than 5 warnings reported by the performance analyzer before submitting to app stores.
- App Store / Play Store approval on first submission with complete metadata, correct privacy labels, and proper age rating, validated using
store_metadata_generator.py.
Scope & Limitations
This skill covers:
- Scaffolding production-ready mobile projects for React Native (Expo Router), Flutter, iOS native (SwiftUI), and Android native (Jetpack Compose).
- Static performance analysis including image asset sizing, re-render detection, memory leak patterns, and bundle size estimation.
- App Store and Play Store metadata generation including titles, keywords, privacy labels, age ratings, and submission checklists.
- Platform-specific architecture patterns (MVVM, state management, navigation).
This skill does NOT cover:
- Backend API development or server-side logic (see
senio