아키텍처
Appify SDK의 구성 요소와 통신 방식을 설명합니다.
3계층 구조
Appify SDK는 세 개의 계층으로 구성됩니다.
웹에서 SDK 메서드를 호출하면 Bridge가 JSON 메시지로 직렬화하여 네이티브에 전달합니다. 네이티브의 MessageRouter가 메시지 키에 따라 핸들러를 실행하고, 결과를 다시 Bridge를 통해 웹으로 반환합니다.
Bridge (브릿지)
브릿지는 웹과 네이티브 사이에서 메시지를 전달하는 통신 계층입니다. 웹 코드는 브릿지를 직접 사용하지 않습니다. SDK 모듈이 내부적으로 브릿지를 통해 네이티브와 통신합니다.
브릿지가 담당하는 역할은 다음과 같습니다.
postMessage 기반 양방향 통신
웹에서 네이티브로 요청을 보낼 때는 window.ReactNativeWebView.postMessage()를 사용합니다. 네이티브에서 웹으로 응답을 받을 때는 window.addEventListener('message', ...)를 통해 수신합니다. 메시지는 모두 JSON 문자열로 직렬화됩니다.
Promise 래핑
SDK 메서드는 모두 Promise를 반환합니다. 브릿지는 요청을 보낸 뒤 응답이 도착하면 해당 Promise를 resolve 또는 reject합니다. 이를 통해 웹 코드는 async/await 문법으로 네이티브 기능을 호출할 수 있습니다.
타임아웃 관리
응답이 일정 시간 내에 도착하지 않으면 브릿지는 해당 Promise를 TimeoutError로 reject합니다. 기본 타임아웃은 30초입니다.
요청 큐잉
동일한 메시지 키에 대해 여러 요청이 동시에 들어오면, 브릿지는 이를 큐에 넣고 순차적으로 처리합니다.
MessageRouter (메시지 라우터)
MessageRouter는 네이티브 앱 내부에 위치하며, 웹에서 전달된 메시지를 적절한 핸들러로 라우팅합니다.
메시지에는 고유한 key 값이 포함됩니다. MessageRouter는 이 키를 기준으로 미리 등록된 핸들러를 조회하고 실행합니다. 예를 들어, BARCODE_SCAN 키가 담긴 메시지가 도착하면 카메라 핸들러가 실행됩니다.
메시지 도착 → key 추출 → 핸들러 조회 → 핸들러 실행 → 응답 반환
핸들러가 등록되어 있지 않은 키의 요청은 에러 응답이 반환되며, 웹 측에서는 { success: false, error: "Unknown message key" } 형태의 응답을 받습니다.
싱글턴 패턴
SDK는 window.appify 전역 인스턴스를 통해 접근합니다. 앱 전체에서 하나의 인스턴스만 존재하며, 초기화 상태와 설정을 공유합니다.
import { appify } from '@nolraunsoft/appify-sdk';
// window.appify와 동일한 인스턴스
await appify.initialize();
SDK를 여러 곳에서 import해도 항상 동일한 인스턴스를 참조합니다.
모듈 시스템
SDK의 각 기능은 독립적인 모듈로 분리되어 있습니다. 모듈은 관련된 기능을 하나로 묶은 단위입니다.
| 모듈 | 접근 경로 | 설명 |
|---|---|---|
| 인증 | appify.auth | 카카오, 네이버, 구글, 애플 소셜 로그인 |
| 카메라 | appify.camera | QR/바코드 스캔 |
| 위치 | appify.location | GPS 현재 위치 조회 |
| 알림 | appify.notification | 푸시 권한, FCM 토큰, 로컬 알림 |
| 디바이스 | appify.device | 기기 정보, 광고 식별자 |
| 저장소 | appify.storage | 네이티브 영구 저장소 |
| 다운로드 | appify.download | 파일, 이미지 다운로드 |
| 클립보드 | appify.clipboard | 텍스트 복사, 붙여넣기 |
| 햅틱 | appify.haptic | 진동 피드백 |
| 공유 | appify.share | 시스템 공유, 카카오톡 공유 |
| 링킹 | appify.linking | 외부 브라우저, 인앱 브라우저, 설정 |
| 리뷰 | appify.review | 인앱 리뷰 요청 |
| 연락처 | appify.contacts | 연락처 조회 |
| 이벤트 | appify.event | 앱 상태 변경 감지 |
| 권한 | appify.permission | 통합 권한 확인, 요청 |
| 분석 | appify.analytics | Firebase Analytics 이벤트 |
각 모듈은 독립적으로 동작하며, 모듈 간 의존성이 없습니다.
// 필요한 모듈만 선택적으로 사용
const info = await appify.device.getInfo();
const position = await appify.location.getCurrentPosition();