Computer >> 컴퓨터 >  >> 시스템 >> Android

iOS와 안드로이드에서 교차 출처 통신 브리지 구축하기: 자바스크립트–네이티브 연동 완벽 가이드

회사에서 진행하던 한 프로젝트에서 여러 이기종 컴포넌트를 메시지 기반으로 연결해야 하는 과제가 있었습니다. 각 컴포넌트는 저마다 고유한 로직과 서로 다른 프로그래밍 언어를 사용하고 있었죠. 이 경험을 계기로 저는 플랫폼 간 통신을 가능하게 해 주는 모든 방식을 제대로 파헤치고 싶어졌습니다.

이 글의 목표는 바로 이러한 교차 출처 통신 브리지(cross-origin communication bridge)의 원리를 설명하고, 직접 구현해 볼 수 있는 간단하지만 알찬 예제를 소개하는 것입니다.

아, 그리고 글곳저곳에 '브리지'를 활용한 말장난이 듬뿍 숨어 있습니다. 미리 경고해 드립니다!

설명보다 코드부터 만져보고 싶으신 분이라면, 글 하단에 GitHub 저장소 링크를 준비해 두었으니 바로 내려가셔도 좋습니다.

일반적으로 우리가 작성한 자바스크립트는 브라우저 환경 안에서 실행됩니다. iOS에서는 UIWebView 또는 WKWebView가, 안드로이드(Android)에서는 WebView가 그 역할을 맡습니다.

iOS가 상대적으로 손이 많이 가는 플랫폼이기 때문에, 먼저 iOS의 통신 브리지부터 살펴보겠습니다.

무너지는 런던 브리지 (iOS)

iOS 8부터 애플은 UIWebView 대신 WKWebView 사용을 공식적으로 권장하고 있습니다. 따라서 이 글에서는 WKWebView 기반의 브리지만 다룹니다. 구버전인 UIWebView 관련 내용이 필요하시다면 별도 문서를 참고하시기 바랍니다.

WKWebView에서 자바스크립트 쪽으로 메시지를 전송하려면 아래 메서드를 사용합니다:

- (void)evaluateJavaScript:(NSString *)javaScriptString 
         completionHandler:(void (^)(id, NSError *error))completionHandler;

반대로 자바스크립트에서 보낸 메시지를 WKWebView에서 수신하려면 다음 단계를 거쳐야 합니다:

  1. WKWebViewConfiguration 인스턴스를 생성합니다.
  2. WKUserContentController 인스턴스를 생성합니다.
  3. 설정(configuration)에 스크립트 메시지 핸들러를 추가합니다. 바로 이 부분이 두 세계를 잇는 브리지 역할을 합니다. 이 과정에서 메시지 핸들러는 window.webkit.messageHandlers.MSG_HANDLER_NAME 경로로 window 객체에 등록됩니다.
  4. 파일 상단에 <WKScriptMessageHandler>를 추가하여 해당 클래스가 메시지 핸들러 프로토콜을 구현하도록 만듭니다.
  5. userContentController:didReceiveScriptMessage 메서드를 구현합니다. 이 메서드가 자바스크립트에서 들어오는 메시지를 실제로 처리합니다.

브리지 구축하기

다음과 같은 HTML 페이지가 준비되어 있다고 가정해 보겠습니다:

<html>
  
  <head>
    <title>Javascript-iOS Communication</title>
  </head>
  
  <body>
    
    <script>
      window.webkit.messageHandlers.myOwnJSHandler.postMessage("Hello World!");
    </script>
  </body>
  
  
</html>

그리고 네이티브 코드에서는 앞서 설명한 단계들을 다음과 같이 구현합니다:

#import <UIKit/UIKit.h>
#import <WebKit/WebKit.h>

// 4
@interface ViewController : UIViewController <WKScriptMessageHandler>

@property(nonatomic, strong) WKWebView *webview;

짜잔! 이것으로 자바스크립트 ↔ iOS 간의 완전한 통신 채널이 열렸습니다!

iOS와 안드로이드에서 교차 출처 통신 브리지 구축하기: 자바스크립트–네이티브 연동 완벽 가이드
Photo by Todd Diemer on Unsplash

브리지 건너기 (Android)

안드로이드 쪽은 훨씬 단순하고 개발자 친화적입니다. 통신 브리지를 설정하는 데 필요한 단계는 딱 몇 가지뿐입니다:

  1. WebView 객체의 인스턴스를 생성합니다.
  2. 해당 WebView에서 자바스크립트를 활성화합니다(setJavaScriptEnabled).
  3. 자체 JavaScript 인터페이스를 설정합니다. 이 인터페이스에는 자바스크립트에서 접근 가능한 메서드들이 담기게 됩니다.
  4. 자바스크립트에 노출하고 싶은 모든 메서드는 선언부 앞에 반드시 @JavascriptInterface 어노테이션을 붙여야 합니다.

마찬가지로 앞서와 같은 형태의 HTML 파일을 만들고, 여기에 간단한 안드로이드 앱 코드만 조합하면 됩니다.

이걸로 끝입니다! 이제 여러분은 당당히 네이티브 통신 닌자(Native Communication Ninja)라고 불러도 좋습니다!

예제 코드가 담긴 저장소 링크는 다음과 같습니다:

• AndroidtoJS 저장소
• iOStoJS 저장소

⚠️ iOS 관련 중요 주의사항 ⚠️

WKWebView를 소멸(destroy)하는 시점에는 반드시 스크립트 메시지 핸들러를 함께 제거해야 합니다. 이를 생략하면 핸들러가 WKWebView에 대한 참조를 계속 붙잡고 있게 되고, 새로운 WKWebView를 생성할 때마다 메모리 누수(memory leak)가 발생합니다. 특히 웹뷰를 반복적으로 띄우는 화면 구조라면 누수가 빠르게 누적되므로 반드시 주의하세요.

마치며

정리하면, iOS의 WKWebView는 messageHandlers 등록과 WKScriptMessageHandler 프로토콜 구현이라는 다소 번거로운 과정을 요구하는 반면, 안드로이드의 WebView는 @JavascriptInterface 어노테이션만으로 간단히 브리지를 완성할 수 있습니다. 두 플랫폼 모두 자바스크립트와 네이티브 코드가 서로를 호출할 수 있는 강력한 통로를 제공하므로, 하이브리드 앱이나 웹뷰 기반 서비스를 개발할 때 이 패턴을 잘 익혀 두면 큰 도움이 될 것입니다.