Skip to content

Repository files navigation

WKJavaScriptController

Calling native code from Javascript in iOS likes JavascriptInterface in Android.

Build Status

Requirements

  • Xcode 11.4+
  • Swift 5.2+
  • iOS8+

(based on WKJavaScriptController 2.1.0+)

Installation with Swift Package Manager

Add the following to your Package.swift:

dependencies:[
// ...
.package(url:"https://github.com/ridi/WKJavaScriptController.git"),]

Usage

import WKJavaScriptController
// Create protocol.
// '@objc' keyword is required. because method call is based on ObjC.
@objcprotocolJavaScriptInterface{func onSubmit(_ dictonary:[String:AnyObject])func onSubmit(_ email:String, firstName:String, lastName:String, address1:String, address2:String, zipCode:JSInt, phoneNumber:String)func onCancel()varisSubmitted:JSBool{get}@objcoptionalfunc getErrorMessages(codes:[JSInt])->[String]}
// Implement protocol. extensionViewController:JavaScriptInterface{func onSubmit(_ dictonary:[String:AnyObject]){NSLog("onSubmit \(dictonary)")}func onSubmit(_ email:String, firstName:String, lastName:String, address1:String, address2:String, zipCode:JSInt, phoneNumber:String){NSLog("onSubmit \(email), \(firstName), \(lastName), \(address1), \(address2), \(zipCode.value), \(phoneNumber)")}func onCancel(){NSLog("onCancel")}varisSubmitted:JSBool{returnJSBool(true)}func getErrorMessages(codes:[JSInt])->[String]{return codes.map{"message\($0)"}}}classViewController:UIViewController{overridefunc viewDidAppear(_ animated:Bool){
super.viewDidAppear(animated)
// Create javaScriptController.
letjavaScriptController=WKJavaScriptController(name:"native", target:self, bridgeProtocol:JavaScriptInterface.self)
// [Optional] Add your javascript.
letconfiguration=WKWebViewConfiguration()letjsCode=...letuserScript=WKUserScript(source: jsCode, injectionTime:.AtDocumentEnd, forMainFrameOnly:true)
userContentController.addUserScript(userScript)
configuration.userContentController = userContentController
// Create WKWebView instance.
webView =WKWebView(frame: view.frame, configuration: configuration)
// Assign javaScriptController.
webView.javaScriptController = javaScriptController
// Call prepareForJavaScriptController before initializing WKWebView or loading page.
webView.prepareForJavaScriptController()
webView.loadRequest(...)}...}
// In javascript.native.onSubmit({'first_name': 'Davin','last_name': 'Ahn','mail': 'davin.ahn@ridi.com',});

Can receive native return in JavaScript as Promise:

// In javascript.constisSubmitted=awaitnative.isSubmitted;// or native.isSubmitted.then(isSubmitted => ...);constmessages=awaitnative.getErrorMessages([200,400,500]);// or native.getErrorMessages([200, 400, 500]).then(messages => ...);

Limitations

  • Can not receive native return in JavaScript as sync. can only async return.
  • Method argument length is up to 10.
  • Allowed argument types are String, Date, Array, Dictionary, JSBool, JSInt, JSFloat, NSNumber and NSNull(when undefined or null passed from JavaScript).
  • If Swift value types(Bool, Int32, Int, Float, Double, ...) used in argument, it must be replaced with JSBool, JSInt or JSFloat. (Because Swift value type is replaced by NSNumber in ObjC.)
  • Class methods in protocol are not supported.

License

MIT

About

Calling native code from Javascript in iOS likes JavascriptInterface in Android.

Topics

Resources

Stars

34 stars

Watchers

15 watching

Forks

Releases

Packages

Used by

Contributors

Languages