[FE] 플러터 앱 전환 프로젝트 webview bridge작업

선영·2025년 1월 22일
0

Front-End

목록 보기
8/8
post-thumbnail

상황

웹뷰에서 플러터 앱 전환을 하고 있었다. 100% 마이그레이션 프로젝트가 아닌, 2주 스프린트로 페이지 단위 마이그레이션이다보니, 기존엔 웹에서 호출하던 api를 네이티브 앱에서 호출하게 되면서 웹에서 앱과의 통신을 통해 웹으로 값을 받아와야 할 일이 많았음

참고로 webview bridge란, 아래와 같은 구조로 webview와 android, ios와의 통신을 위해 만들어진 js용 interface이다. 웹뷰에서 네이티브 동작(메서드, 즉 네이티브 api)를 직접 호출하는 것이 불가능 하기 때문에 bridge라는 통로를 통해 web에서 네이티브 동작을 호출해야 했다.

구현

script 태그를 사용해 javascript 파일을 로드할 때 해당 스크립트는 기본적으로 window 객체의 컨텍스트에서 실행된다.

따라서 스크립트 내에서 정의된 모든 변수와 함수는 window 객체에 바인딩 된다.

// index.html
<script defer type="text/javascript" src="/js/test.plugin.js"></script>

아래와 같이 window.test에 test객체를 바인딩 하고있다. 그래서 window.test.plugin객체에 정의된 프로퍼티에 접근할 수 있는것.

// test.plugin
const test = {
	plugin: { ... }
}

window.test = test;

ui컴포넌트의 핸들러 함수 로직은 아래와 같다.

// Test.tsx
const handleClick = () => {
    window.test.plugin.openView();
  };

앱에서 정의하는 플러터 함수에 대해서 정의해준다. (앱으로 부터 전달받은 파람을 갖고 함수를 정의해준다.)


// test.plugin.js
// web에서 정의하는 플러그인 함수
function openView() {
  const localDb = getLocalDb();
  const message = {
    command: "openView",
    callback: "onReceiveToOpenView",
  };

  if (localDb) {
    // ...생략

    const params = {
      ...message,
    };

    console.log("message", params);

    try {
      flutterCallHandler(params);
    } catch (error) {
      console.error(error);
    }
  }
}

// app에서 호출하는 콜백 함수
function onReceiveToOpenView(data) {
  console.log("onReceiveToOpenView", data);
  const detail = getPayload(data);
  const event = new CustomEvent("onReceiveToOpenView", {
    detail,
  });
  // 여기에서 이벤트를 문서의 dom트리에 전파
  document.dispatchEvent(event);
}

그리고 ui컴포넌트 로직을 아래와 같이 작성해주면 dispatchEvent 로 인해서 해당 핸들러 함수가 동작하게 된다.

// MobileEventHandlerTester.jsx
useEffect(() => {
    document.addEventListener("onReceiveToOpenView", handleReceiveToOpenView);

    return () => {
      document.removeEventListener("onReceiveToOpenView", handleReceiveToOpenView);
    };
  }, []);
  
  
  const handleReceiveToOpenView = ({ detail }) => {
    const localDb = getLocalDb();

    if (localDb) {
      try {
        setDataToLocalDb({
          ...
        });
      } catch (error) {
        console.error(error);
        return;
      }
    }
  };

참고

웹뷰와 브릿지, 스킴

profile
Superduper-India

0개의 댓글

관련 채용 정보