{"id":20564079,"url":"https://github.com/clintjang/sample-swift-wkwebview-javascript-bridge-and-scheme","last_synced_at":"2026-03-07T03:32:24.565Z","repository":{"id":99120075,"uuid":"140252558","full_name":"ClintJang/sample-swift-wkwebview-javascript-bridge-and-scheme","owner":"ClintJang","description":"wkwebview로 javascirpt bridge 방식과 url을 scheme 하는 방식을 셈플링했습니다. (I have tried to sample the method of javascirpt bridge and url scheme with wkwebview.)","archived":false,"fork":false,"pushed_at":"2018-07-19T10:29:45.000Z","size":1291,"stargazers_count":41,"open_issues_count":0,"forks_count":15,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-21T15:41:01.023Z","etag":null,"topics":["html","javascirpt-bridge","javascript","sample","scheme","swift","url-scheme","wkwebview","wkwebview-bridge","wkwebview-javascript-bridge","wkwebview-sample","wkwebview-scheme","wkwebview-uiwebview"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ClintJang.png","metadata":{"files":{"readme":"README-en.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-07-09T08:11:18.000Z","updated_at":"2024-10-31T05:16:38.000Z","dependencies_parsed_at":"2023-06-04T00:15:16.118Z","dependency_job_id":null,"html_url":"https://github.com/ClintJang/sample-swift-wkwebview-javascript-bridge-and-scheme","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ClintJang/sample-swift-wkwebview-javascript-bridge-and-scheme","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ClintJang%2Fsample-swift-wkwebview-javascript-bridge-and-scheme","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ClintJang%2Fsample-swift-wkwebview-javascript-bridge-and-scheme/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ClintJang%2Fsample-swift-wkwebview-javascript-bridge-and-scheme/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ClintJang%2Fsample-swift-wkwebview-javascript-bridge-and-scheme/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ClintJang","download_url":"https://codeload.github.com/ClintJang/sample-swift-wkwebview-javascript-bridge-and-scheme/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ClintJang%2Fsample-swift-wkwebview-javascript-bridge-and-scheme/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30206576,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-07T03:24:23.086Z","status":"ssl_error","status_checked_at":"2026-03-07T03:23:11.444Z","response_time":53,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["html","javascirpt-bridge","javascript","sample","scheme","swift","url-scheme","wkwebview","wkwebview-bridge","wkwebview-javascript-bridge","wkwebview-sample","wkwebview-scheme","wkwebview-uiwebview"],"created_at":"2024-11-16T04:23:50.636Z","updated_at":"2026-03-07T03:32:24.548Z","avatar_url":"https://github.com/ClintJang.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# sample swift wkwebview javascript bridge and scheme\n[![License](http://img.shields.io/badge/License-MIT-green.svg?style=flat)](https://github.com/clintjang/sample-swift-wkwebview-javascript-bridge-and-scheme/blob/master/LICENSE) [![Swift 4](https://img.shields.io/badge/Swift-4.0-orange.svg?style=flat)](https://swift.org) \n\n```\nI have tried to sample the method of javascirpt bridge and url scheme with wkwebview.\n\n★ Web (Front) → Native\nIn the past, when linking with the UIWebView, we had to define a schema in the URL and parse it using scheme information.\nIn WKWebView, there is an additional way to do logic processing with javascript bridge.\n\n★ Native → Web (Front)\nThe native-to-web forwarding / processing method is exactly the same as calling the JavaScript function (\"evaluatejavascript\") as in the existing UIWebView.\n```\n\n- [README.md](https://github.com/ClintJang/sample-swift-wkwebview-javascript-bridge-and-scheme/blob/master/README.md) : 한국어 설명\n\n# Info\n## Result image(GIF)\n\u003cimg width=\"268\" height=\"480\" src=\"/Image/resultLow.gif\"\u003e\n\n## 1. javascirpt bridge\n\u003e There is a distinction between using bridge connections and natively javascript calling back from the web using the scheme of the defined url. \n\n- HTML file for testing: [sampleBridge.html](https://github.com/ClintJang/sample-swift-wkwebview-javascript-bridge-and-scheme/blob/master/JWSWebViewSample/Resources/sampleBridge.html)\n    ```html \n    \u003chtml lang=\"ko\"\u003e\n    \u003chead\u003e\n    \u003cmeta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"\u003e\n    \u003c/head\u003e\n    \u003cscript type=\"text/javascript\"\u003e\n       // alert(1)\n\n        function callNative01() {\n           try {\n               webkit.messageHandlers.callbackHandler.postMessage(\"testValue\");\n           } catch(error) {\n               alert(error)\n           }\n        }\n\n        function callNative02() {\n            try {\n                webkit.messageHandlers.callbackHandler.postMessage({key01:'testValue01', key02:'testValue02'});\n            } catch(error) {\n                alert(error)\n            }\n        }\n\n        function test01() {\n           alert('test01');\n        }\n\n        function testCallBack(message) {\n            alert(message);\n        }\n    \u003c/script\u003e\n    \u003cbody\u003e\n        \u003ch1\u003e \u003ca href=\"javascript:test01();\"\u003eTest Click\u003c/a\u003e \u003c/h1\u003e \u003cbr /\u003e\u003cbr /\u003e\n        \u003ch1\u003e \u003ca href=\"javascript:callNative01();\"\u003eCallNative 01 Click\u003c/a\u003e \u003c/h1\u003e \u003cbr /\u003e\u003cbr /\u003e\n        \u003ch1\u003e \u003ca href=\"javascript:callNative02();\"\u003eCallNative 02 Click\u003c/a\u003e \u003c/h1\u003e \u003cbr /\u003e\u003cbr /\u003e\n    \u003ch1\u003e This is a sample file created to test a simple \"WebView\".\u003cbr /\u003e\u003c/h1\u003e\n    \u003ch1\u003e Modify this file to test the \"WebView\" content.\u003cbr /\u003e\u003c/h1\u003e\n    \u003c/body\u003e\n    \u003c/html\u003e\n    ```\n- swift code : [WebViewBridgeViewController.swift](https://github.com/ClintJang/sample-swift-wkwebview-javascript-bridge-and-scheme/blob/master/JWSWebViewSample/Sample/Bridge/WebViewBridgeViewController.swift) ← Click the details to see the code.\n    ```swift \n    .. (skip).. \n\n    private struct Constants {\n        static let callBackHandlerKey = \"callbackHandler\"\n    }\n\n    .. (skip).. \n\n    func setupView() {\n        // Bridge Setting\n        let userController: WKUserContentController = WKUserContentController()\n        let userScript: WKUserScript = WKUserScript(source: \"test01()\", injectionTime: WKUserScriptInjectionTime.atDocumentEnd, forMainFrameOnly: true)\n        userController.addUserScript(userScript)\n        \n        userController.add(self, name: Constants.callBackHandlerKey)\n        let configuration = WKWebViewConfiguration()\n        configuration.userContentController = userController\n        \n        // Default WebView Setting\n        self.webView = WKWebView(frame:self.safeAreaContainerView.bounds, configuration: configuration)\n        self.webView.navigationDelegate = self\n        self.webView.uiDelegate = self\n        self.webView.translatesAutoresizingMaskIntoConstraints = false\n        \n        self.safeAreaContainerView.addSubview(self.webView)\n        \n        // WKWebView Layout Setting\n        // Constraints like \"UIWebView\" are set.\n        // This is a sample. If you are developing, use a library called \"SnapKit\".\n        // https://github.com/SnapKit/SnapKit\n        let margins = safeAreaContainerView.layoutMarginsGuide\n        webView.leadingAnchor.constraint(equalTo: margins.leadingAnchor).isActive = true\n        webView.trailingAnchor.constraint(equalTo: margins.trailingAnchor).isActive = true\n        webView.topAnchor.constraint(equalTo: margins.topAnchor).isActive = true\n        webView.bottomAnchor.constraint(equalTo: margins.bottomAnchor).isActive = true\n    }\n\n    .. (skip) ..\n\n    // MARK: - WKScriptMessageHandler\n    extension WebViewBridgeViewController : WKScriptMessageHandler {\n        //MARK:- HERE!!!\n    func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {\n          print(\"message.name:\\(message.name)\")\n          if message.name == Constants.callBackHandlerKey {\n              print(\"message.body:\\(message.body)\")\n\n              // Just TEST CallBack\n              if let dictionary = message.body as? Dictionary\u003cString, AnyObject\u003e {\n                  print(dictionary)\n                  var popupPrintString = \"\"\n                  dictionary.forEach { (key, value) in\n                      popupPrintString += \"\\(key):\\(value) \"\n                  }\n                  // call back!\n                  self.webView.stringByEvaluatingJavaScript(script: \"javascript:testCallBack('\\(popupPrintString)');\")\n              } else {\n                  // call back!\n                  self.webView.stringByEvaluatingJavaScript(script: \"javascript:testCallBack('\\(String(describing:message.body))');\")\n              }\n\n              // popup!\n  //            self.webView.stringByEvaluatingJavaScript(script: \"javascript:test01();\")\n\n          }\n      }\n    }\n\n    .. (skip) ..\n\n    ```\n\n## 2. URL Scheme\n\n- HTML file for testing : [sampleScheme.html](https://github.com/ClintJang/sample-swift-wkwebview-javascript-bridge-and-scheme/blob/master/JWSWebViewSample/Resources/sampleScheme.html)\n    ```html \n    \u003chtml lang=\"ko\"\u003e\n    \u003chead\u003e\n    \u003cmeta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\"\u003e\n    \u003c/head\u003e\n\n    \u003cscript type=\"text/javascript\"\u003e\n        //alert(2)\n\n       function callNative01() {\n           window.location = \"nativeScheme://testHost\";\n       }\n\n        function test02() {\n            alert('test02');\n        }\n\n        function testCallBack(message) {\n            alert(message);\n        }\n    \u003c/script\u003e\n    \u003cbody\u003e\n    \u003ch1\u003e \u003ca href=\"javascript:test02();\"\u003eTest Click\u003c/a\u003e \u003c/h1\u003e \u003cbr /\u003e\u003cbr /\u003e\n\n    \u003ch1\u003e \u003ca href=\"javascript:callNative01();\"\u003eCallNative 01 Click\u003c/a\u003e \u003c/h1\u003e \u003cbr /\u003e\u003cbr /\u003e\n\n\n    \u003ch1\u003e This is a sample file created to test a simple \"WebView\".\u003cbr /\u003e\u003c/h1\u003e\n    \u003ch1\u003e Modify this file to test the \"WebView\" content.\u003cbr /\u003e\u003c/h1\u003e\n    \u003c/body\u003e\n    \u003c/html\u003e\n    ```\n\n- swift code : [WebViewSchemesViewController.swift](https://github.com/ClintJang/sample-swift-wkwebview-javascript-bridge-and-scheme/blob/master/JWSWebViewSample/Sample/Scheme/WebViewSchemesViewController.swift) ← Click the details to see the code.\n    ``` swift \n    .. (skip) ..\n\n    private struct Constants {\n        static let schemeKey = \"nativeScheme\"\n    }\n\n    .. (skip) ..\n\n    func setupView() {\n        let preferences = WKPreferences()\n        preferences.javaScriptEnabled = true // default YES.\n        preferences.javaScriptCanOpenWindowsAutomatically = true\n        \n        let configuration = WKWebViewConfiguration()\n        configuration.preferences = preferences\n        \n        self.webView = WKWebView(frame: self.view.bounds, configuration: configuration)\n        self.webView.navigationDelegate = self\n        self.webView.uiDelegate = self\n        self.webView.translatesAutoresizingMaskIntoConstraints = false\n        self.safeAreaContainerView.addSubview(self.webView)\n        \n        // WKWebView Layout Setting\n        // Constraints like \"UIWebView\" are set.\n        // This is a sample. If you are developing, use a library called \"SnapKit\".\n        // https://github.com/SnapKit/SnapKit\n        let margins = safeAreaContainerView.layoutMarginsGuide\n        webView.leadingAnchor.constraint(equalTo: margins.leadingAnchor).isActive = true\n        webView.trailingAnchor.constraint(equalTo: margins.trailingAnchor).isActive = true\n        webView.topAnchor.constraint(equalTo: margins.topAnchor).isActive = true\n        webView.bottomAnchor.constraint(equalTo: margins.bottomAnchor).isActive = true\n    }\n\n    .. (skip) ..\n\n    // MARK: - WKNavigationDelegate\n    extension WebViewSchemesViewController : WKNavigationDelegate {\n\n    .. (skip) ..\n\n    //MARK:- HERE!!!\n    func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -\u003e Void) {\n        print(\"\\(#function)\")\n\n        // Check whether WebView Native is linked\n        if let url = navigationAction.request.url,\n            let urlScheme = url.scheme,\n            let urlHost = url.host,\n            urlScheme.uppercased() == Constants.schemeKey.uppercased() {\n            print(\"url:\\(url)\")\n            print(\"urlScheme:\\(urlScheme)\")\n            print(\"urlHost:\\(urlHost)\")\n\n            decisionHandler(.cancel)\n\n            // call back!\n            self.webView.stringByEvaluatingJavaScript(script: \"javascript:testCallBack('\\(urlHost)');\")\n\n            // popup!\n  //            self.webView.stringByEvaluatingJavaScript(script: \"javascript:test02();\")\n            return\n        }\n        decisionHandler(.allow)\n    }\n\n    .. (skip) ..\n\n    ```\n\n## 3. Common\n- [ViewController.swift](https://github.com/ClintJang/sample-swift-wkwebview-javascript-bridge-and-scheme/blob/master/JWSWebViewSample/ViewController.swift)\n    ```swift\n    .. (skip) ..\n\n    extension WKWebView {\n        func stringByEvaluatingJavaScript(script: String) {\n            self.evaluateJavaScript(script) { (result, error) in\n                \n            }\n        }\n    }\n\n    ```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclintjang%2Fsample-swift-wkwebview-javascript-bridge-and-scheme","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fclintjang%2Fsample-swift-wkwebview-javascript-bridge-and-scheme","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclintjang%2Fsample-swift-wkwebview-javascript-bridge-and-scheme/lists"}