← 홈으로 돌아가기

통신 가이드

네이티브 앱과 웹앱 간 양방향 통신 구현

🔄 통신 아키텍처

Vue/React/Angular 웹앱
        ↓ (JavaScript)
WebBridge.request()
        ↓
  Bridge Channel
        ↓
    네이티브 앱
        ↓
    Native 기능
        ↓
     응답 반환
        ↓
    Promise resolve
        ↓
      웹앱 수신
                

📡 웹앱 → Native

기본 사용법

// JavaScript에서 Native로 메시지 전송
const bridge = new WebBridge();

// 위치 요청
const location = await bridge.getLocation();
console.log(location); // { lat: 37.123, lng: 127.456 }

내부 동작

// 1. 요청 ID 생성
const requestId = generateId();

// 2. Promise 생성 및 저장
const promise = new Promise((resolve, reject) => {
    pendingRequests[requestId] = { resolve, reject };
});

// 3. Native로 메시지 전송
window.NativeBridge.postMessage(JSON.stringify({
    action: 'GET_LOCATION',
    payload: { requestId }
}));

// 4. Promise 반환 (응답 대기)
return promise;

⚙️ 요청-응답 시스템

1. 요청 생성 (웹앱)

async request(action, payload = {}) {
    const requestId = this.generateId();
    
    return new Promise((resolve, reject) => {
        // 타임아웃 설정
        const timeout = setTimeout(() => {
            delete this.pendingRequests[requestId];
            reject(new Error('Request timeout'));
        }, this.timeout);
        
        // 요청 저장
        this.pendingRequests[requestId] = {
            resolve,
            reject,
            timeout
        };
        
        // Native로 전송
        this.sendToNative(action, { ...payload, requestId });
    });
}

4. 응답 수신 (웹앱)

handleResponse(requestId, status, data) {
    const request = this.pendingRequests[requestId];
    
    if (!request) return;
    
    clearTimeout(request.timeout);
    delete this.pendingRequests[requestId];
    
    if (status === 'SUCCESS') {
        request.resolve(data);
    } else {
        request.reject(new Error(data.message));
    }
}

🔐 에러 처리

타임아웃

try {
    const location = await bridge.getLocation();
} catch (error) {
    if (error.message === 'Request timeout') {
        console.log('요청 시간 초과');
    }
}

권한 거부

try {
    const location = await bridge.getLocation();
} catch (error) {
    if (error.message.includes('permission')) {
        console.log('위치 권한이 필요합니다');
    }
}

🎯 실전 예제

Vue 3 Composition API

<script setup>
import { ref } from 'vue';
import WebBridge from './bridge';

const bridge = new WebBridge();
const location = ref(null);
const error = ref(null);

async function getLocation() {
  try {
    location.value = await bridge.getLocation();
  } catch (err) {
    error.value = err.message;
  }
}
</script>

React Hooks

import { useState } from 'react';
import WebBridge from './bridge';

const bridge = new WebBridge();

function App() {
  const [location, setLocation] = useState(null);
  
  const getLocation = async () => {
    try {
      const loc = await bridge.getLocation();
      setLocation(loc);
    } catch (error) {
      console.error(error);
    }
  };
  
  return <button onClick={getLocation}>위치</button>;
}

📊 메시지 형식

요청 메시지

{
  "action": "GET_LOCATION",
  "payload": {
    "requestId": "req_1234567890",
    // 기타 파라미터
  }
}

응답 메시지

{
  "requestId": "req_1234567890",
  "status": "SUCCESS",
  "data": {
    "lat": 37.123,
    "lng": 127.456,
    "accuracy": 10
  }
}

💡 베스트 프랙티스

API 문서에서 모든 기능 확인하기 →