Talently
Talently
Mobile Developer

Mobile Developer

Builds native and cross-platform experiences that users carry in their pocket.

A Mobile Developer designs and implements applications for iOS and Android devices. They may specialize in native development (Swift for iOS, Kotlin for Android) or in cross-platform frameworks such as React Native or Flutter. Their work requires a deep understanding of each platform's specific behaviors, hardware and connectivity constraints, and the design guidelines of each ecosystem. They collaborate closely with UX designers, back-end developers, and QA to deliver smooth, secure experiences that meet app store requirements.

SwiftKotlinReact NativeFlutterXcodeAndroid Studio

Recruit the best Mobile Developer here

Start now

Main Responsibilities

  • Develop and maintain mobile applications for iOS and/or Android following each platform's design guidelines (Apple's HIG, Google's Material Design).
  • Integrate back-end REST or GraphQL APIs with robust error handling, loading states, and offline scenarios.
  • Optimize application performance in terms of animation smoothness, launch time, and battery and memory consumption.
  • Manage the release cycle on the App Store and Google Play, including build signing, permission configuration, and policy compliance.
  • Implement secure local storage, caching, and data synchronization mechanisms for offline support.
  • Write automated UI and business logic tests, and collaborate with QA on real-device testing.

Key Skills

Technical Skills

  • Native development in Swift (iOS) or Kotlin (Android) with deep knowledge of the application lifecycle and its components
  • Cross-platform frameworks: React Native or Flutter for efficient development on both platforms from a shared codebase
  • State management on mobile: Redux, MobX, Riverpod, or native solutions such as SwiftUI's @StateObject and Android's ViewModel
  • REST/GraphQL API consumption with handling for intermittent connectivity, retries, and local caching
  • Local storage with SQLite, Core Data, Room, or Realm depending on the platform and data model complexity
  • Mobile testing: XCTest/Espresso for UI tests, Jest for React Native business logic, and testing across multiple devices and OS versions

Soft Skills

  • Empathy for the mobile user: understanding on-the-go usage contexts, frequent interruptions, and small screen constraints
  • Attention to detail in animations, transitions, and touch behavior that define the app's perceived quality
  • Communication with design to push back on or adapt specifications that are not technically feasible on the target platform
  • Judgment to prioritize which features merit offline support against the complexity that implementing it adds
  • Patience and methodical approach to the app store review and submission process, which involves external timelines and policies
  • Ability to stay current in ecosystems that change significantly with every major iOS and Android release

Real use cases

Context

Consumer apps compete for attention in stores with millions of alternatives. Smoothness, launch time, and the onboarding experience are direct drivers of retention.

Real examples

  • Delivery apps with real-time tracking and integrated payments
  • Video and audio streaming applications with background playback
  • Social networks with infinite feeds, camera functionality, and push notifications
  • Fitness apps with HealthKit and Google Fit integration

Context

B2B or internal-use apps require robust offline support, integration with corporate systems, and strict security policies.

Real examples

  • Inventory and logistics apps with barcode scanning
  • Inspection and audit tools that work without a network connection
  • Sales force apps with CRM synchronization
  • Shift management and attendance tracking with biometric authentication

Context

Financial applications require additional security in data storage, server communication, and user identity verification.

Real examples

  • Digital wallets with biometric authentication and local encryption
  • Investment apps with real-time market quotes
  • Onboarding flows with identity verification (KYC) and document scanning
  • Transfers with OTP confirmation and push notification approval

Context

Mobile unlocks access to hardware unavailable on the web: camera, GPS, sensors, Bluetooth, and NFC. This enables use cases unique to the platform.

Real examples

  • AR applications using ARKit or ARCore for product visualization
  • NFC payments and card reading with tap-to-pay
  • Health apps reading wearable sensor data via Bluetooth LE
  • Document scanning and OCR directly from the camera

Context

When the team is small or time-to-market is the primary constraint, cross-platform frameworks allow sharing business logic and UI between iOS and Android at a reduced maintenance cost.

Real examples

  • Mobile MVPs launched simultaneously on both platforms
  • Internal corporate apps where a premium native experience is not critical
  • Products that share business logic with a web app in the same language
  • Incremental migrations from native apps to React Native module by module

Basic questions

Go native when the app requires deep access to platform-specific APIs, maximum performance for animations or graphics, or integration with specialized hardware. Go cross-platform when the team is small, time-to-market is a priority, or the app doesn't need to differentiate significantly between platforms. The maintenance cost of two native codebases often justifies cross-platform for the majority of business apps.
Implement a local cache layer that serves data when there is no connection. Write operations are queued locally and synced when connectivity is restored. Detect network state with native APIs (Network Framework on iOS, ConnectivityManager on Android) and communicate status to the user clearly, without unnecessarily blocking the UI.
Different navigation models (back button stack on Android vs gestures and navigation bars on iOS), distinct permission flows, virtual keyboard handling differences, notification behavior, and platform design guidelines (Material Design vs HIG). Even with a cross-platform framework, ignoring these differences produces an app that feels out of place on one of the platforms.
Use the secure storage APIs provided by the platform: Keychain on iOS and EncryptedSharedPreferences or the Android Keystore on Android. Never store credentials in unencrypted SharedPreferences, flat files, or the app bundle. For apps with elevated security requirements, require biometric authentication before accessing Keychain entries.
Replace constant polling with push notifications or WebSockets wherever possible. If polling is necessary, use adaptive intervals — more frequent when the app is in the foreground, reduced in the background. Leverage the platform's background fetch APIs, which the OS optimizes for energy efficiency, rather than running your own background processes.
For bugs in business logic or UI that don't require native code changes: use an OTA update system like CodePush (React Native) or remote config. For bugs in native code: submit a hotfix to the app stores, which can take anywhere from hours to days depending on the platform. This is exactly why feature flags and the ability to remotely disable features are critical in production mobile environments.
Define a minimum supported version policy based on the product's actual usage data (or market data for a new app). Use stable APIs and avoid deprecated ones. Run tests against a device matrix using real hardware or services like Firebase Test Lab or AWS Device Farm. Integrate crash reporting (Crashlytics, Sentry) from day one to surface production issues early.
Key navigation events, errors with full stack traces, user context (without PII), app version, OS version, and device model. Use differentiated log levels (debug, info, warning, error) and ensure that debug-level logs never reach production. Integrate a crash reporting service that captures the full app state at the moment of the error.

Technical questions

iOS has five states: Not Running, Inactive, Active, Background, and Suspended. In the Background state, the app has limited time to complete work before being suspended. For longer-running tasks, dedicated APIs exist: BGTaskScheduler for deferred processing, URLSession background mode for downloads. The system can terminate background apps under memory pressure. The app should persist state in applicationWillResignActive and restore it in applicationDidBecomeActive.
Use Instruments (iOS) or Systrace/Perfetto (Android) to identify what work is happening on the main thread during scrolling. Common causes: image decoding on the main thread, synchronous layout calculations, or database access from the UI thread. Solutions: pre-calculate layouts, use AsyncImage or a caching image loading library, move heavy operations to background queues, and implement cell reuse correctly.
Both allow writing asynchronous code with sequential syntax, eliminating callback hell. Swift's async/await integrates with the actor model for thread safety. Kotlin coroutines use CoroutineScope and Dispatchers to control the execution context. The underlying principle is the same in both: suspend execution without blocking the thread, resuming when the result is available. The choice is determined by platform; in Kotlin Multiplatform (KMP) projects, Kotlin coroutines are the natural fit.
Universal Links (iOS) and App Links (Android) allow URLs from your domain to open the app if installed, or fall back to the browser if not. They require hosting a JSON verification file on the server (apple-app-site-association or assetlinks.json) and registering the domains in the app. The OS verifies the association at install time. Link handling occurs in the AppDelegate/SceneDelegate (iOS) or the Activity's intent (Android), where the URL is parsed and the user is navigated to the correct content.
Defer non-essential initialization until after the first visible frame is rendered. Minimize work on the main thread during launch. Reduce the number of frameworks loaded at startup using lazy linking. On iOS, profile with Instruments using the App Launch template. On Android, use startup profiling and AOT compilation. Display a static launch screen while the app loads rather than a blank screen.
Tie all data to a user identifier on the server, not to the device. Implement a sync mechanism based on timestamps or version vectors to detect conflicts. The server is the source of truth; local changes are pushed to the server and server changes are applied locally. For apps with complex sync requirements, evaluate solutions like CloudKit, Firebase Firestore, or a CRDT-based implementation.
Register the device with APNs (iOS) or FCM (Android) and send the device token to the server. The server uses APNs or FCM to deliver notifications. Handle all three states: app in the foreground (show an in-app banner), app in the background (system notification), and app closed (open to the correct context when the notification is tapped). Request permissions at the right moment with clear context explaining why they are needed.
Insecure storage of sensitive data (use Keychain/Keystore). Communication without certificate pinning that is vulnerable to MITM attacks on compromised networks. Binary reverse engineering that exposes keys or sensitive logic (use obfuscation, never hardcode secrets). Excessive permissions requests that undermine user trust. Sensitive data appearing in production logs. Follow the OWASP Mobile Top 10 as a security checklist.

Advanced questions

Implement a local database as the client's source of truth (SQLite with Room, or Core Data). Write operations are applied locally first and queued for sync. When syncing, apply a conflict resolution strategy defined by the business. The server should expose a sync endpoint that accepts a set of local changes and returns the server's changes since a checkpoint. Model data with modification timestamps and soft deletes to facilitate merging.
Use incremental integration: React Native can coexist with native code within the same app. Identify the screens with the least native complexity and migrate those first. Keep the main navigation in native code and mount React Native views at controlled entry points. Measure the impact on bundle size and performance at each phase. Never attempt to migrate everything at once — prioritize based on the business value of each module.
An immutable log of all operations with timestamps and user context. Encryption of sensitive data at rest and in transit. Robust authentication with biometric support and MFA. Certificate pinning to prevent MITM. Session management with automatic timeout. Financial data must never appear in logs or unencrypted backups. The architecture should facilitate external audits by clearly separating the business data layer from the presentation layer.
Testing pyramid: unit tests for business logic and ViewModels, integration tests for components with mocked external services, and a focused suite of UI tests with XCUITest or Espresso. Run the suite against a matrix of priority devices and OS versions on Firebase Test Lab or BrowserStack. Complement with snapshot tests to catch visual regressions. The goal is confidence in critical user flows, not line coverage.
Implement client-side request deduplication: prevent multiple parallel calls for the same resource using a request coalescing mechanism. Use aggressive caching with a stale-while-revalidate strategy to reduce server requests. Implement exponential backoff with jitter for retries to avoid a thundering herd when the server recovers from an incident. On the server side, enforce per-user rate limiting and circuit breakers to protect back-end services.
Automate builds and code signing with Fastlane or GitHub Actions. Use schemes and flavors to isolate environments (dev, staging, prod) without modifying code. Implement internal distribution with TestFlight and Firebase App Distribution for QA. Use semantic versioning and automate version bumps in the pipeline. For production releases, use staged rollouts to detect issues before reaching 100% of users. Maintain a documented rollback runbook.

Common interview mistakes

Saying 'I use React Native and it works the same on iOS and Android' signals inexperience. A strong mobile developer knows the differences in UX patterns, OS behavior, and native API access, and can explain which parts of their cross-platform solution require platform-specific code.
Proposing implementations that do heavy work on the main thread, load images without caching, or render long lists without virtualization shows a lack of real-world experience with mobile hardware constraints. Interviewers at companies with high-traffic apps specifically probe for these scenarios.
App Store review can take days and reject a release for non-technical reasons. Not having accounted for this in hotfix planning — or never having worked with CodePush or feature flags to mitigate the rigidity of the submission process — is a clear signal of limited real-world mobile experience.
Proposing to store tokens in unencrypted AsyncStorage in React Native, or in SharedPreferences on Android, is a common and serious mistake. A mobile developer must know the secure storage APIs available on each platform and why the default storage options are insufficient for sensitive data.
Mobile is not simply a smaller front end. Proposing features without considering battery consumption, mobile data usage, small screen UX, or intermittent usage patterns shows that the candidate is thinking about mobile as if it were a desktop application.
Advocating for React Native or Flutter in every scenario without being able to articulate their real limitations — access to newly released native APIs, heavy compute performance, bundle size — is just as problematic as always dismissing them. Interviewers assess whether you can make that call with sound technical and business judgment.