WebView 플랫폼 분기를 상징하는 갈림길 표지판 일러스트
Cordova 앱은 결국 WebView 위에서 돌아가다 보니, Android/iOS 차이를 “웹처럼” 간단히 처리할 수 있을 것 같지만 의외로 분기 지점이 여러 군데에 흩어져 있습니다. JS 코드만 나눴는데도 빌드가 깨지거나, iOS에서만 권한/설정이 빠져 런타임에서 터지는 식이죠.

아래는 Cordova에서 플랫폼 분기를 설계할 때, 헷갈리기 쉬운 포인트를 한 번에 정리한 Android/iOS 분기 가이드입니다.

먼저 “어디에서 분기할지(빌드 타임 vs 런타임)”를 결정하면 대부분의 문제가 줄어듭니다.

1) 분기 전략부터 정하기: 빌드 타임 vs 런타임

플랫폼 분기는 크게 두 가지입니다.

  • 빌드 타임 분기: config.xml, plugin 변수, platform별 파일/리소스, (필요 시) hooks로 처리. “해당 플랫폼에서 아예 포함/제외”가 목적일 때 적합합니다.
  • 런타임 분기: JS에서 device.platform / cordova.platformId 등을 보고 동작을 바꿈. “같은 바이너리에서 실행 시점에 다르게 동작”이 목적일 때 적합합니다.

권장 흐름은 간단합니다. “설정/권한/플러그인 구성 차이”는 빌드 타임으로, “UI/로직 차이”는 런타임으로 보내세요. 반대로 섞으면, iOS에서만 필요한 설정이 누락되어 앱 심사/테스트 단계에서 늦게 발견되는 경우가 많습니다.

빌드 타임과 런타임 분기 흐름을 보여주는 도식

2) JS 런타임 분기: device.platform vs cordova.platformId 안전하게 쓰기

WebView 런타임 분기는 대개 다음 이벤트 이후에 해야 안전합니다.

  • deviceready 이후: Cordova 플러그인 및 device 정보가 준비되기 전 접근하면 undefined가 나올 수 있습니다.

실무에서 자주 쓰는 값은 두 가지입니다.

  • cordova.platformId: 'ios', 'android' 같은 소문자 ID를 반환(일관성이 좋아 추천)
  • device.platform: 'iOS', 'Android'처럼 대소문자/표기가 달라 비교 실수가 잦음

예시로는 아래처럼 “한 번 정규화해서 쓰는 방식”이 실수를 줄입니다.

  • platform = (cordova.platformId || '').toLowerCase()로 통일
  • 분기 조건은 platform === 'ios', platform === 'android'처럼 최소화

그리고 WebView 관련 로직(예: status bar 여백, safe-area 처리, 키보드 동작)은 iOS/Android에서 UX가 꽤 다르니, 화면 단위로 분기하기보다 “레이아웃 유틸 함수”처럼 공통 모듈에서 분기하도록 구조를 잡는 편이 유지보수에 좋습니다.

덧붙여, iOS에서만 터지는 케이스 중 하나가 “플러그인은 설치되어 있는데 JS는 호출하고, 실제 네이티브 설정은 빠진 상태”입니다. 이건 런타임 분기로 해결이 안 되고 빌드 타임 설정을 봐야 합니다.

3) config.xml에서 플랫폼별 설정 분기(자주 쓰는 패턴)

config.xml은 Cordova에서 가장 먼저 봐야 하는 “빌드 타임 분기 지점”입니다. 다음 패턴을 기억해두면 편합니다.

  • <platform name="ios"> ... </platform> 안에 iOS 전용 preference/설정 배치
  • <platform name="android"> ... </platform> 안에 Android 전용 설정 배치
  • 공통 설정은 platform 블록 밖에 두되, 특정 플랫폼에서만 다른 값이 필요하면 플랫폼 블록에서 “덮어쓰기”가 가능한지 플러그인 문서를 확인

특히 WebView 관련 preference(예: WKWebView 사용, mixed content, viewport 관련)는 프로젝트/플러그인 조합에 따라 지원 여부가 달라질 수 있습니다. “config.xml에 썼으니 적용됐겠지”가 가장 위험한 포인트라서, 적용 여부는 빌드 산출물(iOS는 Xcode 프로젝트 설정/Info.plist, Android는 AndroidManifest.xml 등)로 꼭 확인하세요.

4) 플러그인/권한 분기: iOS만 필요한 키, Android만 필요한 권한

WebView 기반 앱에서도 플러그인은 결국 네이티브 권한/설정에 의존합니다. 플랫폼 분기에서 많이 실수하는 지점은 다음입니다.

  • iOS Info.plist 문구(Usage Description) 누락: 카메라/사진/위치 등은 빌드가 성공해도 실행이나 심사에서 문제가 됩니다.
  • Android 권한/특성 누락: AndroidManifest.xml에 들어가야 할 권한이나 feature가 빠져 런타임에서 기능이 제한됩니다.
  • “플러그인 설치”와 “플러그인 설정”을 혼동: 설치만으로는 끝이 아니고, 변수/설정이 필요한 경우가 많습니다.

가장 안전한 방법은 “플러그인별로 iOS/Android 체크리스트를 갖고 가는 것”입니다.

  • iOS: 필요한 Info.plist 키가 들어갔는지, entitlement가 필요한지 확인
  • Android: 권한, queries(패키지 조회), fileprovider, network security 설정 등 확인
  • 공통: 플러그인 버전이 Cordova/플랫폼 버전과 호환되는지 확인

5) WebView 동작 차이로 생기는 이슈를 분기 없이 줄이는 방법

분기를 많이 만들수록 유지보수가 어려워집니다. WebView 특성 차이는 “분기”보다는 “흡수”하는 방향이 실무적으로 편합니다.

  • 네트워크/보안 정책: iOS ATS, Android cleartext traffic 등은 각자 설정을 맞추되, 앱 로직은 동일한 URL/프로토콜 정책을 쓰도록 정리
  • 뷰포트/안전영역: iOS safe-area는 CSS(env(safe-area-inset-*))로 최대한 해결하고, 부족한 부분만 iOS 분기
  • 키보드: iOS는 입력 포커스/스크롤 보정이 민감하니, 화면 공통 컴포넌트에서 처리(개별 화면에서 땜질 분기 금지)
  • 외부 링크/인앱 브라우저: window.open 동작 차이를 줄이기 위해 InAppBrowser 같은 플러그인을 쓰는 경우, 호출 인터페이스는 공통 래퍼로 통일

즉, “플랫폼별로 다른 점”을 앱 전체에 흩뿌리기보다, WebView/디바이스 환경에 닿는 경계면(유틸/서비스 레이어)에 모아두면 분기 관리가 쉬워집니다.

플랫폼별 설정 점검을 위한 체크리스트 일러스트

6) 실무 체크리스트: Android/iOS 분기에서 가장 많이 놓치는 것

  • deviceready 이전에 분기 로직 실행 (cordova/device 값이 아직 없음)
  • cordova.platformId와 device.platform을 섞어 비교 (대소문자/표기 차이로 오동작)
  • config.xml에 쓴 설정이 실제 산출물에 반영됐는지 미확인 (Info.plist, AndroidManifest.xml 등으로 검증 필요)
  • iOS Info.plist Usage Description 누락 (테스트/심사에서 지연 유발)
  • Android에서만 필요한 네트워크/파일 정책 미설정 (cleartext/fileprovider 등)
  • 분기를 UI 곳곳에 분산 (나중에 수정할 때 누락 발생)

이 체크리스트를 통과하도록 구조를 잡으면, 플랫폼 분기 때문에 생기는 “되는 기기만 되는” 문제를 상당히 줄일 수 있습니다.

마무리

Cordova WebView의 Android/iOS 분기는 “JS 한 줄 if문”으로 끝나는 문제가 아니라, 빌드 타임 설정과 런타임 로직이 함께 맞아야 안정적입니다.

분기 지점을 최소화하고(경계면에 모으고), config.xml/권한/산출물 확인을 루틴으로 만들면 유지보수 난이도가 확 내려갑니다.