Back

WebView <-> Native Interface 개선 라이브러리 소개

WebView는 계륵이다

WebView를 사용하지 않을 수 없을까?

여러 프로젝트에서 WebView는 껄끄러운 존재입니다. Native의 아키텍쳐와는 별개로 구성하여야 하고, WebView만의 여러 설정법이 있기 때문입니다. (수많은 버그는 덤이다)
이런 WebView를 아예 사용하지 않으면 좋겠으나 기획, 마케팅에서 원하는 모든 정보 혹은 UI를 Native 영억에서 100% 컨트롤 할 수 없는 사항이 생기므로, 프로젝트 어딘가 한켠에 WebView를 사용해야 하는 경우가 많이 발생합니다.

진짜 귀찮은 것은 인터페이스

WebView가 정말로 귀찮은 이유는 바로 WebPage와의 Interface입니다.
대표적인 사항으로 다음과 같은 것들이 있는데,

  1. Android와 iOS 각각의 Interface구현 방법이 다르다
  2. WebPage상에서 Android, iOS의 Interface 구현체 구조가 서로 다르다.
  3. 결과값(Return)을 전달하기가 애매하다.
    1. Android의 JavaScriptBridge는 비동기로 결과값 전달이 불가능하며, Array 및 Map 형태의 데이터를 사용 할 수 없다.
    2. iOS의 UserContentController는 결과값을 전달하기 위한 장치를 별도로 구축해야 한다.

이러한 문제점들을 해결 하고자 추가 자원(인적, 시간)이 필연적으로 발생하게 됩니다.
필자는 프로젝트들을 진행하면서, 이런 문제점들을 해결하고 공통화한 라이브러리를 제작하였습니다.

라이브러리 소개

링크 - Android용, iOS용

주요 특징

  1. 구조가 유사한 kotlin의 lambda와 swift의 closure을 각각 사용하여, 인터페이스시 동작할 사항을 정의 할 수 있다.
  2. WebPage에서의 구현체는 동일하며, 별도의 js파일을 삽입할 필요가 없다. WebVeiw에서 필요한 스크립트를 제작하여 WebPage에 주입한다.
  3. 결과값(Return)전달이 가능하고 비동기(WebPage의 Promise 패턴)방식을 통해 인터페이스 된다.

간단 사용법

  1. WebView에 인터페이스를 등록.
/*
 * Android Kotlin
 */

val testLambda : FlexLambda.array = 
{ arguments -> // arguments에는 WebPage에서 전달받을 값들이 담겨 있음
    arrayOf(1,2,3) // [1,2,3] 배열을 리턴
}

// WebView에 testLambda가 동작하는 testInterface 등록
// 첫번째 인자는 WebPage에서 사용할 인터페이스 함수명,
// 두번재 인자는 인터페이스 시 동작할 lambda
mWebView.arrayInterface("testInterface", testLambda)
/*
 * iOS Swift
 */

let testClosure : FlexClosure.array = 
{ arguments -> Array<Any?>? in // arguments에는 WebPage에서 전달받을 값들이 담겨 있음
    return [1,2,3]
}

// FlexComponent WKWebViewConfiguration 을 포함하며 WebView에 Interface를 전달하기 위한 객체
let component = FlexComponent()
// WebView에 testClosure가 동작하는 testInterface 등록
// 첫번째 인자는 WebPage에서 사용할 인터페이스 함수명,
// 두번재 인자는 인터페이스 시 동작할 lambda
component.arrayInterface("testInterface", testClosure)
let mWebView = FlexWebView(frame: self.view.frame, component: component)
  1. WebPage에서 함수 사용
/*
 * Android Kotlin
 */

// WebView를 로드하면, WebPage에 인터페이스가 자동으로 등록.
mWebView.loadUrl(someUrl)
/*
 * iOS Swift
 */

// WebView를 로드하면, WebPage에 인터페이스가 자동으로 등록.
mWebView.load(someUrl)
/*
 * WebPage
 */
async function test() {
    // $flex 객체가 WebPage에 자동으로 생성
    // WebView에서 등록한 testInterface가 자동으로 $flex의 하위 객체로 생성
    // $flex의 인터페이스는 Promise를 리턴
    // Android, iOS 모두 동일하여 코드 이원화 할 필요 X
    const testArray = await $flex.testInterface(); // [1,2,3]
}

마무리

해당 라이브러리는 더 많은 추가 기능과 사용법이 있으므로, 관심이 있다면 Repository(Android용, iOS용)에 방문하여 확인 해 주시면 감사드립니다!

comments powered by Disqus