Welcome :っ)

Devlog/Next.js

Next.js 웹뷰와 네이티브 앱 연동 (인증 연동 방법)

lazy.won 2025. 3. 11. 17:23
728x90
반응형

 

 

 

 

 

 

들어가며..

웹뷰(Next.js)에서 네이티브 앱(iOS/Android)과 연동하여 인증(Face ID, PIN..)을 처리하는 과정 중 무지함 때문에 주말에 집도 못 가고 새벽까지 붙잡고 있었다.. ㅎㅎ

 

앱팀에서 정의한 onResult() 라는 함수를 Next.js (React) 코드 내에 정의해 두면 네이티브에서 인증 처리를 한 후 다시 웹뷰로 인증 결과를 onResult()를 통해 전달하는 방식이다. 

 

처음에는 단순히 onResult 함수만 정의하면 네이티브 앱이 해당 함수를 직접 호출할 수 있다고 생각했는데.. 아니었다.

 

 

 

 

💡 네이티브 → 웹뷰 호출 

웹뷰 내에서 실행되는 JavaScript와 네이티브 앱이 서로 다른 실행 환경에서 동작하기 때문에 단순히 onResult함수를 정의하면 네이티브 앱이 해당 함수를 직접 호출할 수 없다.

Next.js 코드 내에서 단순히 onResult 함수를 정의하면, 이 함수는 React 컴포넌트 내부에 존재하는 일반 함수일 뿐이다.

 

🤔 그럼? window 객체를 이용해야 한다.

 

네이티브 앱(Swift/Kotlin)에서 웹뷰에 데이터를 전달하려면, JavaScript 실행 환경에 접근해야 한다. 

이를 위해서 evaluateJavaScript (iOS) 또는 evaluateJavascript (Andorid) 메서드를 사용해서 JS 코드를 실행하는 방식이 일반적이라고 한다.

 

// iOS (Swift)
func returnToWebView(result: String, webView: WKWebView) {
    let jsCode = "window.onResult('\(result)');"  // window 객체의 onResult 호출
    webView.evaluateJavaScript(jsCode, completionHandler: nil)
}

 

// Android (Kotlin)
fun returnToWebView(result: String, webView: WebView) {
    val jsCode = "window.onResult('$result');"
    webView.post {
        webView.evaluateJavascript(jsCode, null)
    }
}

 

네이티브에서 실행할 수 있는 코드는 "window.onResult('success');" 같은 문자열 형태의 JavaScript 코드이다.

즉, 네이티브 앱이 웹뷰에서 직접 특정 함수를 호출하려면 window 객체에 해당 함수를 등록해야 한다. 

 

 

 

 

인증 흐름 및 구현 방법

1️⃣ 웹뷰(Next.js)에서 네이티브 앱 호출

  1. 웹뷰에서 window.location.href를 사용하여 네이티브 앱의 딥링크 실행
  2. 네이티브 앱이 열리면서 인증 화면으로 이동
const openNativeAuth = () => {
  window.location.href = `${APP_REQUEST_AUTH_URL}`;
};

 

2️⃣ 네이티브 앱에서 인증 진행

  1. 사용자가 PIN 또는 Face ID 인증 수행
  2. 인증이 완료되면 웹뷰로 돌아갈 URL을 포함하여 다시 웹뷰를 연다.

 

3️⃣ 네이티브 앱에서 웹뷰로 결과 전달

  1. 웹뷰는 onResult(resultLstring) 함수를 통해 인증 결과를 받는다.
  2. 웹뷰 상태가 유지된 상태에서 결과를 처리한다.
useEffect(() => {
  // onResult 함수를 전역 객체에 등록
  window.onResult = (result: string) => {
    console.log('네이티브 인증 결과:', result);
    if (result === 'success') {
      alert('인증 성공!');
    } else {
      alert('인증 실패');
    }
  };
}, []);

 

 

😳 그런데 여기서, 타입스크립트에서는 window 객체에 onResult 같은 커스텀 속성을 추가하면 타입 오류가 발생한다.  ("window에 없는 속성" 오류 발생..)

 

그래서 window 전역 객체 타입 확장이 필요하다. 

// global.d.ts 파일

export {};

declare global {
  interface Window {
    onResult: (result: string) => void;
  }
}

 

 

 

 

정리

  • 웹뷰의 실행 환경과 네이티브 앱의 실행 환경은 다르다.
  • 네이티브에서 웹뷰로 데이터를 전달하려면 웹뷰의 JavaScript 실행 환경(window 객체)에 접근해야 한다.
  • window.onResult 처럼 전역 객체에 함수를 등록하면, 네이티브 앱이 evaluateJavaScript를 통해 해당 함수를 실행할 수 있다.

 

 

 

 

 

 

 

 

320x100