← Back to Finn
AgentFinn
Mobile native integration
Defines reliable boundaries between cross-platform application code and platform-specific native capabilities.
mobile-native-integration
See how it helpsWhen is it useful?
Use when a feature needs an SDK or device function beyond existing framework APIs.
What does it help you do?
- Chooses the integration mechanism supported by the actual project.
- Specifies typed requests, threading, cancellation and error propagation.
- Updates native manifests and build configuration without losing existing setup.
Try asking this
Integrate a native document scanner with cancellation and explicit errors when the capability is unavailable.
Detailed documentation
Read the skill’s original instructions, examples and checks in their authored language.
Show less
Native Platform Integration
Encapsulate iOS (Swift / Objective-C / SwiftUI) and Android (Kotlin / Jetpack Compose) platform APIs behind narrow, type-safe interfaces so application screens and domain logic remain portable and testable.
1. Choose the right native integration mechanism
- Check existing SDK & community modules first: before writing custom native code, verify whether an official Expo SDK module, RN community package or Flutter plugin already supports the capability.
- When custom native code is required:
- Expo / React Native:
- Prefer the Expo Modules API (
ModuleDSL in Swift and Kotlin withFunction,AsyncFunction,Events,View) for clean lifecycle hooks and automatic type bridging. - In bare React Native on the New Architecture, define typed Codegen specs (
specs/Native<Name>.tsextendingTurboModulewithTurboModuleRegistry.getEnforcing<Spec>) and Fabric view components.
- Prefer the Expo Modules API (
- Flutter:
- Prefer Pigeon (
@HostApi()/@FlutterApi()) to generate type-safe Dart, Swift and Kotlin contracts without untyped dictionary casting. - When using
MethodChannelorEventChanneldirectly, namespace channel names (com.example.app/<feature>), validate argument maps, and handlePlatformExceptionandMissingPluginException.
- Prefer Pigeon (
- Pure Native (SwiftUI / Jetpack Compose):
- On iOS, isolate hardware/OS frameworks (
AVFoundation,CoreLocation,LocalAuthentication,StoreKit,BackgroundTasks) in@MainActoror actor-isolated service protocols injected into@Observableview models. - On Android, isolate
Context-bound system services,ActivityResultLaunchercontracts andBroadcastReceiverregistrations behind repository/controller interfaces injected via Hilt/Koin/manual DI.
- On iOS, isolate hardware/OS frameworks (
- Expo / React Native:
2. Design a resilient boundary contract
- Single cross-platform wrapper: expose one domain-level TypeScript or Dart module (
biometricVault.ts,documentScanner.dart). UI components must never branch on raw iOSNSErrordomains or AndroidIntentextras. - Capability & simulator fallback: expose an explicit availability check (
isAvailableAsync()) and degrade gracefully on iOS Simulator, Android Emulator without Google Play Services, or older OS versions (if #available(iOS 17, *),Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE). - Threading & lifecycle discipline:
- Never block the iOS main thread (
DispatchQueue.main) or Android main looper (Dispatchers.Main) with file I/O, image transcoding, encryption or synchronous IPC. - Clean up native event emitters,
NotificationCenterobservers,BroadcastReceiverinstances and hardware sessions when the JS/Dart listener detaches or the hostActivity/UIViewControllerpauses.
- Never block the iOS main thread (
3. Native project configuration, manifests and build safety
- iOS (
Info.plist,*.entitlements,Podfile, Xcode):- Add specific
NS...UsageDescriptionkeys for every protected capability, requiredUIBackgroundModes, Associated Domains (applinks:) and Privacy Manifest declarations (PrivacyInfo.xcprivacyrequired reason APIs).
- Add specific
- Android (
AndroidManifest.xml,build.gradle(.kts),proguard-rules.pro):- Declare minimal
<uses-permission>entries,<uses-feature android:required="false" />when hardware is optional (so Google Play does not hide the app on tablets/devices without that sensor), Android 14+android:foregroundServiceTypeattributes, and@Keep/ ProGuard rules for classes serialized across the bridge in release builds.
- Declare minimal
- Expo CNG rule: in managed/prebuild projects, encode all
Info.plist, entitlement andAndroidManifest.xmlchanges inapp.json/app.config.tsor a Config Plugin (withInfoPlist,withAndroidManifest) sonpx expo prebuild --cleanstays reproducible. - Release impact: any native code, Podfile, Gradle or manifest change requires a new binary build (and a
runtimeVersionbump for OTA updates).
Before you finish
- Native bridge wrapped behind a single typed service with simulator and OS fallbacks.
- Heavy native work runs off the main thread; native observers and hardware sessions cleaned up.
- iOS (
Info.plist,PrivacyInfo.xcprivacy, entitlements) and Android (AndroidManifest.xml,foregroundServiceType, ProGuard/R8) configs complete. - Requirement for a new native binary build documented in the handoff.
Included files 2
LICENSE.txtSKILL.md
