From harness-claude
Advises on mobile lifecycle management, permissions, deep linking, push notifications, and app store compliance for iOS, Android, React Native, Flutter, and Expo with platform-specific best practices.
npx claudepluginhub intense-visions/harness-engineering --plugin harness-claudeThis skill uses the workspace's default tool permissions.
> Advise on mobile platform lifecycle management, permission handling, deep linking, push notifications, and app store submission compliance. Covers iOS, Android, React Native, and Flutter with platform-specific best practices.
Audits iOS/iPadOS/macOS app projects against App Store Review Guidelines before submission. Supports Swift/ObjC, Flutter, React Native, Expo, Kotlin Multiplatform, .NET MAUI, Cordova/Ionic, Unity.
Audits mobile apps for app size, startup time, crash reporting, store compliance, accessibility, and offline behavior across iOS, Android, React Native, and Flutter.
Guides mobile app development for iOS/Android/cross-platform (React Native, Flutter): platform assessment, architecture (MVVM/MVI/Clean), setup, signing, store submission, performance, and features like push/deep links.
Share bugs, ideas, or general feedback.
Advise on mobile platform lifecycle management, permission handling, deep linking, push notifications, and app store submission compliance. Covers iOS, Android, React Native, and Flutter with platform-specific best practices.
Resolve project root. Use provided path or cwd.
Detect mobile platform and framework. Scan for:
app.json, App.tsx, react-native.config.js, node_modules/react-nativepubspec.yaml, lib/main.dart, android/, ios/*.xcodeproj, *.xcworkspace, Info.plist, AppDelegate.swiftAndroidManifest.xml, build.gradle, *.kt or *.java in app/src/app.json with expo key, eas.json, expo-modules-autolinkingInventory platform configurations. Read and catalog:
Info.plist (permissions, URL schemes, associated domains), Entitlements.plist, provisioning profile referencesAndroidManifest.xml (permissions, intent filters, deep links), build.gradle (target SDK, dependencies), google-services.jsonapp.json (display name, bundle ID), native module links, Podfilepubspec.yaml (dependencies), platform-specific configs under ios/ and android/Detect feature implementations. Scan source code for:
requestPermission, checkPermission, NSLocationWhenInUseUsageDescription, uses-permissionLinking.addEventListenerAppState.addEventListener, onPause/onResume, WidgetsBindingObserver, applicationDidEnterBackgroundCheck build and signing configuration. Verify:
Report detection summary:
Mobile Platform Detection:
Framework: React Native 0.73 (Expo managed workflow)
Platforms: iOS 15+ (deployment target), Android API 24+ (minSdkVersion)
Bundle ID: com.example.myapp (consistent across platforms)
Permissions: camera, photo library, push notifications, location (when in use)
Deep linking: URL scheme registered, universal links not configured
Push: Firebase Cloud Messaging (Android), APNs (iOS)
Build: 3 variants (debug, staging, release)
Audit permission handling. For each declared permission:
NSUsageDescription strings present for every requested permission?Audit deep linking. Evaluate:
myapp://) Are conflicts possible with other apps?apple-app-site-association file configured? Is applinks: domain in entitlements?intent-filter with autoVerify="true" configured? Is assetlinks.json hosted?Audit push notification setup. Evaluate:
Audit lifecycle management. Check:
Audit app store readiness. Check:
Classify findings by severity:
Generate permission handling recommendations. For each finding:
Generate deep linking setup guide. Based on what is missing:
apple-app-site-association template, entitlement configuration, and server-side hosting instructionsassetlinks.json template, intent-filter XML, and verification stepsGenerate push notification checklist. Provide:
Generate store submission checklist. Provide:
Recommend lifecycle improvements. Provide:
Verify permission configuration completeness. For each permission in code:
Verify deep link routing. For each registered deep link pattern:
Verify push notification flow. End-to-end:
Output mobile patterns report:
Mobile Patterns Report: [PASS/NEEDS_ATTENTION/FAIL]
Platform: React Native 0.73 (iOS + Android)
Permissions (4 declared):
camera: OK (point-of-use request, denial handled, description clear)
location: WARNING (requested at launch, should be point-of-use)
push: OK (requested after onboarding, token registered)
photo_library: ERROR (missing NSPhotoLibraryUsageDescription in Info.plist)
Deep Linking:
URL scheme: OK (myapp:// registered on both platforms)
Universal Links: NOT_CONFIGURED (recommended for iOS)
App Links: NOT_CONFIGURED (recommended for Android)
Auth handling: WARNING (deep link to /profile without auth check)
Push Notifications:
iOS (APNs): OK
Android (FCM): WARNING (no notification channels for API 26+)
Foreground handling: OK
Background handling: OK
Terminated handling: MISSING
Store Readiness:
iOS: NEEDS_ATTENTION (missing privacy nutrition labels for location)
Android: NEEDS_ATTENTION (target SDK 33, Play Store requires 34+)
ERRORS: 1 | WARNINGS: 4 | INFO: 2
Cross-reference platform configs. Verify iOS and Android configurations are consistent:
harness skill run harness-mobile-patterns -- Primary command for mobile platform auditing.harness validate -- Run after applying configuration changes to verify project health.Glob -- Used to locate platform configs (Info.plist, AndroidManifest.xml), native modules, and framework files.Grep -- Used to find permission requests, deep link handlers, notification setup, and lifecycle methods in source code.Read -- Used to read platform manifests, entitlements, build configurations, and native module source.Write -- Used to generate configuration templates, apple-app-site-association files, and store submission checklists.Bash -- Used to check Xcode project settings, Gradle configurations, and run platform-specific validation commands.emit_interaction -- Used to present the audit report and confirm recommendations before generating configuration changes.Phase 1: DETECT
Framework: React Native 0.73 (Expo SDK 50, managed workflow)
Platforms: iOS 16+, Android API 26+
Permissions: camera, notifications, location-when-in-use
Deep linking: expo-linking configured, no universal links
Push: expo-notifications with FCM
Phase 2: ANALYZE
[MOB-ERR-001] app.json
Missing NSCameraUsageDescription -- will cause App Store rejection
[MOB-WARN-001] src/screens/HomeScreen.tsx:15
Location permission requested on mount, not when map feature is used
[MOB-WARN-002] No notification channel configuration for Android
[MOB-INFO-001] expo-linking handles deep links but no deferred deep link support
Phase 3: ADVISE
Add to app.json plugins: ["expo-camera", { cameraPermission: "Take photos for your profile" }]
Move location request to MapScreen component
Add expo-notifications channel creation in App.tsx useEffect
Consider expo-linking with web fallback for deferred deep links
Phase 4: VALIDATE
Permissions complete after fix: YES
Deep link routing covers auth state: NO (needs auth check)
Store readiness: iOS PASS (after fix), Android NEEDS_ATTENTION (target SDK)
Phase 1: DETECT
Framework: Flutter 3.19, Dart 3.3
Platforms: iOS 14+, Android API 23+
Dependencies: firebase_messaging, firebase_dynamic_links, permission_handler
Permissions: camera, microphone, storage, notifications
Phase 2: ANALYZE
[MOB-ERR-001] android/app/build.gradle
targetSdkVersion 33 -- Play Store requires 34+ for new submissions
[MOB-ERR-002] lib/services/push_service.dart
onMessageOpenedApp handler missing -- tapped notifications from background do nothing
[MOB-WARN-001] lib/main.dart
All 4 permissions requested in initState -- should be contextual
[MOB-WARN-002] ios/Runner/Info.plist
NSMicrophoneUsageDescription: "Microphone access" -- too vague
Phase 3: ADVISE
Update targetSdkVersion to 34 and test for behavioral changes
Implement FirebaseMessaging.onMessageOpenedApp handler with navigation
Move permission requests to feature screens (camera on photo screen, mic on voice screen)
Update description: "Record voice messages to send to your team"
Phase 4: VALIDATE
Config consistency iOS vs Android: 3/4 permissions aligned (storage is Android-only, OK)
Push flow complete after fix: YES (foreground + background + terminated)
Store readiness after fixes: iOS PASS, Android PASS
Phase 1: DETECT
Framework: Native iOS (Swift 5.9, Xcode 15)
Deployment target: iOS 16.0
Capabilities: push notifications, associated domains, HealthKit
Permissions: health-share, health-update, notifications, location-always
Phase 2: ANALYZE
[MOB-ERR-001] Info.plist
Missing NSHealthShareUsageDescription for HealthKit read access
[MOB-ERR-002] Runner.entitlements
Associated domains list includes staging URL -- remove before production build
[MOB-WARN-001] AppDelegate.swift
Location-always permission requested without location-when-in-use fallback
Apple may reject: must request when-in-use first, then upgrade to always
[MOB-WARN-002] Privacy manifest (PrivacyInfo.xcprivacy) not present
Required for iOS 17+ submissions using required reason APIs
Phase 3: ADVISE
Add NSHealthShareUsageDescription: "View your daily step count and activity trends"
Create separate entitlements files for staging and production
Implement progressive location permission: when-in-use first, then always with explanation
Generate PrivacyInfo.xcprivacy with required reason API declarations
Phase 4: VALIDATE
All permission descriptions present after fix: YES
Entitlements clean for production: YES (after staging URL removal)
Privacy manifest complete: YES (after generation)
Store submission ready: PASS
| Rationalization | Reality |
|---|---|
| "We request all permissions at launch to get them out of the way — users can deny them if they want." | App stores treat permissions-at-launch as a review red flag and users deny at much higher rates when there is no contextual explanation. Permissions requested at the moment they are needed, with a sentence explaining why, consistently achieve higher grant rates and reduce store rejection risk. |
| "Universal Links are optional — the URL scheme fallback works fine for deep linking." | URL scheme fallbacks (myapp://) can be claimed by any installed app on the device. A malicious or coincidentally named app can intercept links intended for yours. Universal Links with verified apple-app-site-association files are cryptographically bound to your domain and cannot be hijacked. |
| "The push notification handler works in foreground and background — we can handle the terminated state separately after launch." | Users often first interact with an app by tapping a push notification when the app is terminated. The cold-start tap handler is commonly the first impression. Shipping without it means a class of users experiences a broken entry point from day one. |
| "The staging configuration is slightly different but we'll remember to change it before the App Store build." | "Remember to change it" is not a process. Staging URLs, debug API keys, and sandbox APNs environments in production builds have shipped before and will again. Separate build configurations and environment-specific entitlement files are the only reliable mitigation. |
| "The privacy manifest requirement is new — we'll add it in the next release after the store flags it." | Apple has enforced PrivacyInfo.xcprivacy requirements for new submissions and updates since May 2024. Submitting without it results in rejection, which blocks the entire release. Adding it retroactively under rejection pressure is strictly more costly than adding it now. |
ios/ and android/ directories. Consider if an existing library covers this use case.".well-known/apple-app-site-association on your web domain. This needs coordination with the web/infrastructure team."