← 홈으로 돌아가기

라이브러리 사용법

고급 기능과 최적화 팁

⚙️ 고급 설정

브릿지 옵션

const bridge = new FlutterBridge({
  debug: true,          // 디버그 로그
  timeout: 15000,       // 타임아웃 15초
  retries: 3,           // 자동 재시도
  throwOnError: false   // 에러 시 throw 여부
});

이벤트 리스너

// Flutter에서 보낸 이벤트 수신
window.addEventListener('flutter-event', (event) => {
  console.log('Flutter 이벤트:', event.detail);
});

// 위치 업데이트 이벤트
window.addEventListener('location-updated', (event) => {
  const { lat, lng } = event.detail;
  updateMap(lat, lng);
});

🔄 상태 관리

Vue Pinia

// stores/bridge.ts
import { defineStore } from 'pinia';
import FlutterBridge from '@/utils/flutter-bridge';

export const useBridgeStore = defineStore('bridge', {
  state: () => ({
    bridge: new FlutterBridge({ debug: true }),
    location: null,
    deviceInfo: null
  }),
  
  actions: {
    async fetchLocation() {
      this.location = await this.bridge.getLocation();
    }
  }
});

React Context

// BridgeContext.tsx
import { createContext, useContext } from 'react';
import FlutterBridge from './flutter-bridge';

const BridgeContext = createContext(null);

export function BridgeProvider({ children }) {
  const bridge = new FlutterBridge({ debug: true });
  return (
    <BridgeContext.Provider value={bridge}>
      {children}
    </BridgeContext.Provider>
  );
}

export const useBridge = () => useContext(BridgeContext);

🎯 실전 패턴

로딩 상태 관리

const [loading, setLoading] = useState(false);

async function getLocation() {
  setLoading(true);
  try {
    const loc = await bridge.getLocation();
    setLocation(loc);
  } catch (error) {
    console.error(error);
  } finally {
    setLoading(false);
  }
}

에러 핸들링

try {
  const photo = await bridge.takePhoto();
} catch (error) {
  if (error.message.includes('permission')) {
    showPermissionDialog();
  } else if (error.message === 'Request timeout') {
    showTimeoutMessage();
  } else {
    showGenericError();
  }
}

중복 요청 방지

let pendingRequest = null;

async function getLocation() {
  if (pendingRequest) {
    return pendingRequest;
  }
  
  pendingRequest = bridge.getLocation();
  const result = await pendingRequest;
  pendingRequest = null;
  
  return result;
}

💾 캐싱 전략

메모리 캐싱

class BridgeCache {
  constructor(bridge) {
    this.bridge = bridge;
    this.cache = new Map();
  }
  
  async getDeviceInfo() {
    if (this.cache.has('deviceInfo')) {
      return this.cache.get('deviceInfo');
    }
    
    const info = await this.bridge.getDeviceInfo();
    this.cache.set('deviceInfo', info);
    return info;
  }
}

TTL 캐싱

class TTLCache {
  constructor(ttl = 60000) {
    this.cache = new Map();
    this.ttl = ttl;
  }
  
  set(key, value) {
    this.cache.set(key, {
      value,
      expires: Date.now() + this.ttl
    });
  }
  
  get(key) {
    const item = this.cache.get(key);
    if (!item) return null;
    if (Date.now() > item.expires) {
      this.cache.delete(key);
      return null;
    }
    return item.value;
  }
}

🚀 성능 최적화

배치 요청

// 여러 요청을 한 번에
const [location, deviceInfo, data] = await Promise.all([
  bridge.getLocation(),
  bridge.getDeviceInfo(),
  bridge.loadData('user')
]);

Debounce

import { debounce } from 'lodash';

const debouncedSave = debounce(async (data) => {
  await bridge.saveData('draft', data);
}, 1000);

// 1초 후에 저장
debouncedSave({ title: '제목' });

🐛 디버깅

디버그 모드

const bridge = new FlutterBridge({ debug: true });

// 콘솔에 모든 요청/응답 출력
// [Bridge] Request: GET_LOCATION
// [Bridge] Response: { lat: 37.123, lng: 127.456 }

로깅

class LoggingBridge extends FlutterBridge {
  async request(action, payload) {
    console.time(action);
    try {
      const result = await super.request(action, payload);
      console.timeEnd(action);
      return result;
    } catch (error) {
      console.error(`${action} failed:`, error);
      throw error;
    }
  }
}

예제 파일에서 더 많은 패턴 확인하기 →