PABCD Initiative Documentation Hub pabcd_initiative codexclaw cli-jaw

Mobile Native UX Conventions

Source: dev-uiux-design/references/mobile-native-ux.md

Mobile Native UX Conventions

Last reviewed: 2026-06-16

Applies to: iOS 18+, Android 15+, cross-platform (RN/Flutter/KMP)

When to read: Native mobile app UX decisions, platform conventions, deep linking, app store submission, task_tags: mobile_native

Canonical owner: dev-uiux-design — platform UX judgment (when/why)

Non-goals: Framework selection and code patterns (→ dev-frontend/references/stacks/mobile-native.md), push/offline API (→ dev-backend/references/core/mobile-api.md), mobile web UX (→ dev-frontend/references/core/mobile-ux.md)

---

§1 Platform UX Conventions

ConventioniOS (HIG)Android (Material 3)Cross-Platform Guidance
NavigationTab bar (bottom), back via swipe-rightBottom nav bar, back via system gesture/buttonUse platform-native nav; don't force iOS tabs on Android or vice versa
Primary actionRight side of nav bar or prominent buttonFAB (56dp) or top app bar actionRespect platform placement; FAB on Android, bar button on iOS
Destructive confirmAction sheet from bottomDialog (centered)Use platform-native confirmation pattern
Pull to refreshNative UIRefreshControl spinnerSwipeRefresh circular indicatorUse platform-native indicator; don't custom-animate
SettingsSystem Settings deep link for permissionsIn-app settings screeniOS: link to Settings app for system permissions; Android: handle in-app
TypographySF Pro (system), Dynamic Type support mandatoryRoboto (system), sp units for accessibility scalingAlways use system font; support dynamic/accessibility text sizing
HapticsUIImpactFeedbackGenerator (light/medium/heavy)HapticFeedbackConstants (confirm/reject/long press)Map semantic haptics to platform API; never skip on destructive actions

Platform detection decision

ApproachWhenRisk Single UI, platform-adaptive widgetsMVP, small team, content-heavy appsMay feel "off" to power users
Platform-specific UI shells, shared logicProduction apps, platform-critical UXHigher maintenance, better native feel
Fully native per platformFinance, health, OS-integrated apps2x effort, best UX

---

§2 Native Gestures

GestureiOSAndroidUsage
Swipe-to-dismissinteractiveDismissTransition / sheet detentpredictiveBackGesture (Android 14+)Modal/detail screens; always provide alternative close button
Long pressUIContextMenuInteraction (peek/pop)onLongClickListener → context menuSecondary actions; discoverable via visible menu icon
Pinch zoomUIPinchGestureRecognizerScaleGestureDetectorImages, maps; show zoom controls for accessibility
Edge swipeSystem back gesture (left edge)System back (both edges on gesture nav)Never override system back; use popGesture only within app nav
Pull downRefresh (UIRefreshControl)Notification shade (system)iOS: pull-to-refresh is standard; Android: avoid pull-to-refresh conflict with notification shade

Gesture conflict resolution

ConflictResolution
Horizontal swipe (carousel) vs edge-backInset carousel 16dp from edges; let edge gesture pass through
Pull-to-refresh vs scroll-upTrigger refresh only when scrollY === 0
Bottom sheet drag vs list scrollLock sheet drag when inner list is scrollable and scrollY > 0

---

§3 Deep Linking

// apple-app-site-association (AASA) — host at /.well-known/
{
  "applinks": {
    "apps": [],
    "details": [{
      "appID": "TEAMID.com.example.app",
      "paths": ["/product/*", "/invite/*", "/u/*"]
    }]
  }
}
// assetlinks.json — host at /.well-known/
[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.example.app",
    "sha256_cert_fingerprints": ["AB:CD:..."]
  }
}]

Deferred deep linking (first install)

MethodMechanismAccuracy
Clipboard-basedCopy link → app reads on first launchHigh but requires user consent prompt (iOS 16+)
Fingerprint matchingIP + UA + timestamp → match install to click~80%, degrades with VPN/carrier NAT
Platform SDKFirebase Dynamic Links (deprecated) → use Branch.io or AdjustHigh, third-party dependency

Korean in-app browser fallback

카카오톡, 네이버 앱 내 브라우저는 Universal Links/App Links를 무시하는 경우가 많다.

PlatformWorkaround
KakaoTalk in-appIntent scheme (intent://...#Intent;scheme=myapp;package=com.example.app;end) for Android; iOS는 kakaolink:// scheme으로 외부 브라우저 유도
Naver in-appnaversearchapp:// intent or JavaScript bridge openExternalBrowser()
General fallbackwindow.location.href = "myapp://path" → setTimeout → redirect to store
// Universal fallback pattern for Korean in-app browsers
function openAppOrStore(appUrl, iosStore, androidStore) {
  const ua = navigator.userAgent;
  const isAndroid = /android/i.test(ua);
  const isKakao = /kakaotalk/i.test(ua);
  const isNaver = /naver/i.test(ua);

  if (isAndroid && (isKakao || isNaver)) {
    // Intent scheme bypasses in-app browser restrictions
    location.href = `intent://${appUrl}#Intent;scheme=myapp;package=com.example.app;S.browser_fallback_url=${encodeURIComponent(androidStore)};end`;
  } else {
    location.href = `myapp://${appUrl}`;
    setTimeout(() => {
      location.href = isAndroid ? androidStore : iosStore;
    }, 1500);
  }
}

---

§4 Onboarding & Permissions

Permission request timing

PermissionWhen to AskNever Ask
Push notificationsAfter first value delivery (e.g., first order placed)On app launch before any interaction
CameraWhen user taps "scan" or "take photo"During onboarding
LocationWhen showing map or nearby resultsBefore showing why location is needed
ContactsWhen user taps "invite friends"During onboarding
Tracking (ATT)After explaining personalized experience benefitAs the very first screen (iOS rejects)

Korean privacy compliance (개인정보보호법)

RequirementImplementation
개인정보 수집·이용 동의Separate consent checkbox, not bundled with terms of service
마케팅 수신 동의Opt-in (not opt-out), separate from service consent
만 14세 미만Legal guardian consent required; age gate before signup
수집 항목 명시List exact fields collected (이름, 이메일, 전화번호) in consent screen
보유 기간State retention period explicitly ("회원 탈퇴 시까지" or specific duration)
┌─────────────────────────────────┐
│  [서비스 이용약관] (필수) [보기>] │  ☑
│  [개인정보 수집·이용] (필수) [보기>]│  ☑
│  [마케팅 수신 동의] (선택) [보기>]  │  ☐
│  [위치정보 이용] (선택) [보기>]     │  ☐
│                                   │
│  [전체 동의]                       │
│  [다음]                           │
└─────────────────────────────────┘

---

§5 App Store UX

Screenshot specifications

StoreSize (iPhone 16 Pro Max)Size (Pixel 9 Pro)Count
App Store1320 × 2868 px (6.9")3-10 per locale
Google Play1080 × 2400 px2-8 per locale
RuleDetail First 2 screenshotsMust show core value proposition; 80% of users decide without scrolling further
Text overlayMax 5 words per screenshot, 60pt+ font, high contrast
Locale adaptationKorean screenshots for KR store (not English with Korean subtitle)
Status barShow realistic status bar (time, signal, battery) or crop above it

App icon requirements

PlatformSizeShapeNotes
iOS1024 × 1024 pxAuto-masked to rounded squareNo transparency; no alpha channel
Android1024 × 1024 px (foreground) + 512 × 512 px (background)Adaptive icon (foreground + background layers)Safe zone: inner 66% circle for foreground content
BothTest at 29px (notification), 60px (home), 1024px (store)

---

§6 Anti-Patterns & Pre-flight

Anti-patterns

BannedSymptomFix
iOS-style bottom tabs on AndroidUsers expect Material bottom nav behavior (no swipe between tabs)Use platform-native navigation component
Custom back button overriding system gesturePredictive back animation breaks, user disorientedUse system back; add close button only as secondary
Permission request on first launchLow opt-in rate (<30%), user distrustAsk at point of need with pre-prompt explaining value
Alert dialog for everythingUser fatigue, dismissed without readingAction sheets (iOS) / bottom sheets (Android) for choices; dialogs only for confirmations
Ignoring Dynamic Type / sp scalingAccessibility failure, app store rejection riskTest at largest accessibility text size

Pre-flight checklist

  • [ ] Navigation uses platform-native pattern (tab bar iOS, bottom nav Android)
  • [ ] All gestures have accessible button alternatives
  • [ ] Deep links configured: AASA (iOS) + assetlinks.json (Android) validated
  • [ ] Korean in-app browser (KakaoTalk, Naver) fallback tested
  • [ ] 개인정보 수집·이용 동의 separate from 이용약관, 마케팅 opt-in separate
  • [ ] Screenshots prepared per locale with Korean text for KR store
  • [ ] App icon tested at 29px, 60px, 1024px; Android adaptive icon safe zone verified
  • [ ] Dynamic Type (iOS) / sp scaling (Android) tested at max accessibility size