GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — GitHub - ridi/WKJavaScriptController: Calling native code from Javascript in iOS likes JavascriptInterface in Android.

BranchesTags
Open more actions menu

Latest commit

 

History

107 Commits
107 Commits

Folders and files

NameName
Last commit message
Last commit date
.swiftpm/xcode/package.xcworkspace
.swiftpm/xcode/package.xcworkspace
 
 
Demo
Demo
 
 
Sources/WKJavaScriptController
Sources/WKJavaScriptController
 
 
.gitignore
.gitignore
 
 
.swift-version
.swift-version
 
 
.swiftformat
.swiftformat
 
 
.swiftlint.yml
.swiftlint.yml
 
 
.travis.yml
.travis.yml
 
 
CHANGELOG.md
CHANGELOG.md
 
 
LICENSE
LICENSE
 
 
Package.swift
Package.swift
 
 
README.md
README.md
 
 

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.
@objc protocol JavaScriptInterface {
    func onSubmit(_ dictonary: [String: AnyObject])
    func onSubmit(_ email: String, firstName: String, lastName: String, address1: String, address2: String, zipCode: JSInt, phoneNumber: String)
    func onCancel()
    var isSubmitted: JSBool { get }
    @objc optional func getErrorMessages(codes: [JSInt]) -> [String]
}

// Implement protocol. 
extension ViewController: 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")
    }
    
    var isSubmitted: JSBool {
        return JSBool(true)
    }
    
    func getErrorMessages(codes: [JSInt]) -> [String] {
        return codes.map { "message\($0)" }
    }
}

class ViewController: UIViewController {
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        
        // Create javaScriptController.
        let javaScriptController = WKJavaScriptController(name: "native", target: self, bridgeProtocol: JavaScriptInterface.self)
        
        // [Optional] Add your javascript.
        let configuration = WKWebViewConfiguration()
        
        let jsCode = ...
        let userScript = 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': '[email protected]',
});

Can receive native return in JavaScript as Promise:

// In javascript.
const isSubmitted = await native.isSubmitted;
// or native.isSubmitted.then(isSubmitted => ...);
const messages = await native.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

iosjavascriptjavascriptinterfaceswiftwkwebview

Resources

Readme
MIT license
Activity
Custom properties

Stars

34 stars

Watchers

15 watching

Forks

13 forks
Report repository

Releases

Packages

Used by

Contributors

Languages

You are visitor 01402520 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.