Code Monkey home page Code Monkey logo

clintjang / sample-swift-wkwebview-javascript-bridge-and-scheme Goto Github PK

View Code? Open in Web Editor NEW
36.0 3.0 13.0 1.26 MB

wkwebview로 javascirpt bridge 방식과 url을 scheme 하는 방식을 셈플링했습니다. (I have tried to sample the method of javascirpt bridge and url scheme with wkwebview.)

License: MIT License

Swift 90.80% HTML 9.20%
wkwebview wkwebview-uiwebview wkwebview-bridge wkwebview-scheme wkwebview-javascript-bridge sample wkwebview-sample swift url-scheme scheme

sample-swift-wkwebview-javascript-bridge-and-scheme's Introduction

sample swift wkwebview javascript bridge and scheme

License Swift 4

WKWebview로 javascirpt bridge 방식과 url을 scheme 하는 방식을 셈플링했습니다.

★ 웹(프론트) → 네이티브
예전에는 UIWebView에서 연동시 기존에는 URL에 스키마를 정의해서 내려받은 스킴정보를 이용해서 파싱해서 처리했었습니다.
WKWebView에서는 추가적으로 javascript bridge를 사용해서 편하게 로직 처리를 할 수 있는 방법이 있습니다. 

★ 네이티브 → 웹(프론트)
웹(프론트) → 네이티브 로 전달방식은 추가된 방식이 있지만, 
네이티브 → 웹(프론트) 로 전달/처리 방식은 기존에 자바스크립트 함수를 호출하던 1가지(evaluatejavascript) 그대로 입니다.

아래는 그 기능들에 대한 셈플링을 해봤습니다. 

설명

결과 이미지 (GIF)

1. javascirpt bridge 방식

브릿지 연결을 이용한 것과 정의된 url의 스킴을 이용한 웹에서 네이티브로 콜백을 주는 구분이 있습니다.

  • 테스트를 위한 HTML 파일 : sampleBridge.html
    <html lang="ko">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    </head>
    <script type="text/javascript">
       // alert(1)
    
        function callNative01() {
           try {
               webkit.messageHandlers.callbackHandler.postMessage("testValue");
           } catch(error) {
               alert(error)
           }
        }
    
        function callNative02() {
            try {
                webkit.messageHandlers.callbackHandler.postMessage({key01:'testValue01', key02:'testValue02'});
            } catch(error) {
                alert(error)
            }
        }
    
        function test01() {
           alert('test01');
        }
    
        function testCallBack(message) {
            alert(message);
        }
    </script>
    <body>
        <h1> <a href="javascript:test01();">Test Click</a> </h1> <br /><br />
        <h1> <a href="javascript:callNative01();">CallNative 01 Click</a> </h1> <br /><br />
        <h1> <a href="javascript:callNative02();">CallNative 02 Click</a> </h1> <br /><br />
    <h1> This is a sample file created to test a simple "WebView".<br /></h1>
    <h1> Modify this file to test the "WebView" content.<br /></h1>
    </body>
    </html>
  • swift code 처리 부분 : WebViewBridgeViewController.swift ← 자세한것은 클릭해서 코드를 보세요.
    .. (중략).. 
    
    private struct Constants {
        static let callBackHandlerKey = "callbackHandler"
    }
    
    .. (중략).. 
    
    func setupView() {
        // Bridge Setting
        let userController: WKUserContentController = WKUserContentController()
        let userScript: WKUserScript = WKUserScript(source: "test01()", injectionTime: WKUserScriptInjectionTime.atDocumentEnd, forMainFrameOnly: true)
        userController.addUserScript(userScript)
        
        userController.add(self, name: Constants.callBackHandlerKey)
        let configuration = WKWebViewConfiguration()
        configuration.userContentController = userController
        
        // Default WebView Setting
        self.webView = WKWebView(frame:self.safeAreaContainerView.bounds, configuration: configuration)
        self.webView.navigationDelegate = self
        self.webView.uiDelegate = self
        self.webView.translatesAutoresizingMaskIntoConstraints = false
        
        self.safeAreaContainerView.addSubview(self.webView)
        
        // WKWebView Layout Setting
        // Constraints like "UIWebView" are set.
        // This is a sample. If you are developing, use a library called "SnapKit".
        // https://github.com/SnapKit/SnapKit
        let margins = safeAreaContainerView.layoutMarginsGuide
        webView.leadingAnchor.constraint(equalTo: margins.leadingAnchor).isActive = true
        webView.trailingAnchor.constraint(equalTo: margins.trailingAnchor).isActive = true
        webView.topAnchor.constraint(equalTo: margins.topAnchor).isActive = true
        webView.bottomAnchor.constraint(equalTo: margins.bottomAnchor).isActive = true
    }
    
    .. (중략) ..
    
    // MARK: - WKScriptMessageHandler
    extension WebViewBridgeViewController : WKScriptMessageHandler {
        //MARK:- HERE!!!
    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
          print("message.name:\(message.name)")
          if message.name == Constants.callBackHandlerKey {
              print("message.body:\(message.body)")
    
              // Just TEST CallBack
              if let dictionary = message.body as? Dictionary<String, AnyObject> {
                  print(dictionary)
                  var popupPrintString = ""
                  dictionary.forEach { (key, value) in
                      popupPrintString += "\(key):\(value) "
                  }
                  // call back!
                  self.webView.stringByEvaluatingJavaScript(script: "javascript:testCallBack('\(popupPrintString)');")
              } else {
                  // call back!
                  self.webView.stringByEvaluatingJavaScript(script: "javascript:testCallBack('\(String(describing:message.body))');")
              }
    
              // popup!
    //            self.webView.stringByEvaluatingJavaScript(script: "javascript:test01();")
    
          }
      }
    }
    
    .. (중략) ..

2. URL의 Scheme를 이용해서 처리하는 방식

  • 테스트를 위한 HTML 파일 : sampleScheme.html

    <html lang="ko">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    </head>
    
    <script type="text/javascript">
        //alert(2)
    
       function callNative01() {
           window.location = "nativeScheme://testHost";
       }
    
        function test02() {
            alert('test02');
        }
    
        function testCallBack(message) {
            alert(message);
        }
    </script>
    <body>
    <h1> <a href="javascript:test02();">Test Click</a> </h1> <br /><br />
    
    <h1> <a href="javascript:callNative01();">CallNative 01 Click</a> </h1> <br /><br />
    
    
    <h1> This is a sample file created to test a simple "WebView".<br /></h1>
    <h1> Modify this file to test the "WebView" content.<br /></h1>
    </body>
    </html>
  • swift code 처리 부분 : WebViewSchemesViewController.swift ← 자세한것은 클릭해서 코드를 보세요.

    .. (중략) ..
    
    private struct Constants {
        static let schemeKey = "nativeScheme"
    }
    
    .. (중략) ..
    
    func setupView() {
        let preferences = WKPreferences()
        preferences.javaScriptEnabled = true // default YES.
        preferences.javaScriptCanOpenWindowsAutomatically = true
        
        let configuration = WKWebViewConfiguration()
        configuration.preferences = preferences
        
        self.webView = WKWebView(frame: self.view.bounds, configuration: configuration)
        self.webView.navigationDelegate = self
        self.webView.uiDelegate = self
        self.webView.translatesAutoresizingMaskIntoConstraints = false
        self.safeAreaContainerView.addSubview(self.webView)
        
        // WKWebView Layout Setting
        // Constraints like "UIWebView" are set.
        // This is a sample. If you are developing, use a library called "SnapKit".
        // https://github.com/SnapKit/SnapKit
        let margins = safeAreaContainerView.layoutMarginsGuide
        webView.leadingAnchor.constraint(equalTo: margins.leadingAnchor).isActive = true
        webView.trailingAnchor.constraint(equalTo: margins.trailingAnchor).isActive = true
        webView.topAnchor.constraint(equalTo: margins.topAnchor).isActive = true
        webView.bottomAnchor.constraint(equalTo: margins.bottomAnchor).isActive = true
    }
    
    .. (중략) ..
    
    // MARK: - WKNavigationDelegate
    extension WebViewSchemesViewController : WKNavigationDelegate {
    
    .. (중략) ..
    
    //MARK:- HERE!!!
    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
        print("\(#function)")
    
        // Check whether WebView Native is linked
        if let url = navigationAction.request.url,
            let urlScheme = url.scheme,
            let urlHost = url.host,
            urlScheme.uppercased() == Constants.schemeKey.uppercased() {
            print("url:\(url)")
            print("urlScheme:\(urlScheme)")
            print("urlHost:\(urlHost)")
    
            decisionHandler(.cancel)
    
            // call back!
            self.webView.stringByEvaluatingJavaScript(script: "javascript:testCallBack('\(urlHost)');")
    
            // popup!
    //            self.webView.stringByEvaluatingJavaScript(script: "javascript:test02();")
            return
        }
        decisionHandler(.allow)
    }
    
    .. (중략) ..

3. 공통

  • ViewController.swift
    .. (중략) ..
    
    extension WKWebView {
        func stringByEvaluatingJavaScript(script: String) {
            self.evaluateJavaScript(script) { (result, error) in
                
            }
        }
    }

sample-swift-wkwebview-javascript-bridge-and-scheme's People

Contributors

clintjang avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.