SkillAgentSearch skills...

Kamome

Kamome is a library for iOS and Android apps using the WebView. This library bridges a gap between JavaScript in the WebView and the native code written in Swift, Java, or Kotlin.

Install / Use

/learn @HituziANDO/Kamome
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

Kamome

release npm Pod Version Carthage Compatible Swift Package Manager compatible

Kamome is a library for iOS and Android apps using the WebView. This library bridges a gap between JavaScript in the WebView and the native code written in Swift, Java or Kotlin.

<img src="./README/images/illustration.png" width="410">

Kamome provides common JavaScript interface for iOS and Android.

If you build Flutter apps with the WebView, see kamome_flutter for the Flutter plugin.

Quick Usage

Sends a message from the JS code to the native code

  1. Sends a message from the JavaScript code

    // JavaScript
    
    import { KM } from "kamome"
    
    // Uses async/await.
    try {
        // Sends `echo` command.
        const result = await KM.send('echo', { message: 'Hello' });
        // Receives a result from the native code if succeeded.
        console.log(result.message);
    } catch(error) {
        // Receives an error from the native code if failed.
        console.log(error);
    }
    
  2. Receives a message on iOS

    // Swift
    
    private lazy var webView: WKWebView = {
        let webView = WKWebView(frame: self.view.frame)
        return webView
    }()
    
    private var client: Client!
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        // Creates the Client object with the webView.
        client = Client(webView)
    
        // Registers `echo` command.
        client.add(Command("echo") { commandName, data, completion in
            // Received `echo` command.
            // Then sends resolved result to the JavaScript callback function.
            completion.resolve(["message": data!["message"]!])
            // Or, sends rejected result if failed.
            //completion.reject("Echo Error!")
        })
    
        let htmlURL = Bundle.main.url(forResource: "index", withExtension: "html", subdirectory: "www")!
        webView.loadFileURL(htmlURL, allowingReadAccessTo: htmlURL)
        view.addSubview(webView)
    }
    

    [NOTE] This framework supports WKWebView only. UIWebView is not supported.

  3. Receives a message on Android

    // Kotlin
    
    private var client: Client? = null
    
    override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContentView(R.layout.activity_main)
    
       val webView = findViewById<WebView>(R.id.webView)
    
       // Creates the Client object with the webView.
       client = Client(webView)
    
       // Registers `echo` command.
       client.add(Command("echo") { commandName, data, completion ->
           // Received `echo` command.
           // Then sends resolved result to the JavaScript callback function.
           val map = HashMap<String?, Any?>()
           map["message"] = data!!.optString("message")
           completion.resolve(map)
           // Or, sends rejected result if failed.
           //completion.reject("Echo Error!")
       })
    
       webView.loadUrl("file:///android_asset/www/index.html")
    }
    

Sends a message from the native code to the JS code

  1. Sends a message from the native code on iOS

    // Swift
    
    // Send a data to the JS code.
    client.send(["greeting": "Hello! by Swift"], commandName: "greeting") { (commandName, result, error) in
        // Received a result from the JS code.
        guard let result = result else { return }
        print("result: \(result)")
    }
    
  2. Sends a message from the native code on Android

    // Kotlin
    
    // Sends a data to the JS code.
    val data = HashMap<String?, Any?>()
    data["greeting"] = "Hello! by Kotlin"
    client?.send(data, "greeting") { commandName, result, error ->
       // Received a result from the JS code.
       Log.d(TAG, "result: $result")
    }
    
  3. Receives a message on the JavaScript code

    // JavaScript
    
    // Adds a receiver that receives a message sent by the native client.
    KM.addReceiver('greeting', (data, resolve, reject) => {
        // The data is the object sent by the native client.
        console.log(data.greeting);
    
        // Runs asynchronous something to do...
        setTimeout(() => {
    
            // Returns a result as any object or null to the native client.
            resolve('OK!');
            // If the task is failed, call `reject()` function.
            //reject('Error message');
        }, 1000);
    });
    

Include Library in Your Project

1. JavaScript

npm

  1. npm install

    npm install kamome
    
  2. Write following import statement in JavaScript

    import { KM } from "kamome"
    

Manual Installation

  1. Download latest Kamome SDK

  2. Import kamome.umd.js

    <script src="/path/to/kamome.umd.js"></script>
    <script>
      const KM = window.Kamome.KM;
    </script>
    

2. iOS App

Swift Package Manager

Kamome is available through Swift Package Manager. To install it using Xcode, specify the git URL for Kamome.

https://github.com/HituziANDO/kamome.git

CocoaPods

Kamome is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod "kamome"

Carthage

Kamome is available through Carthage. To install it, simply add the following line to your Cartfile:

github "HituziANDO/kamome"

You run the following command in the Terminal.

carthage update --use-xcframeworks

Manual Installation

  1. Download latest Kamome SDK
  2. Drag & drop kamome.xcframework into your Xcode project
  3. Click General tab in your target
  4. In Frameworks, Libraries, and Embedded Content, Select "Embed & Sign" for kamome.xcframework

Import Framework

Write the import statement in your source code

import kamome

3. Android App

Gradle

Add the following code in build.gradle(project level).

allprojects {
    repositories {
        maven {
            url 'https://hituziando.github.io/kamome/android/repo'
        }
    }
}

Add the following code in build.gradle(app level).

dependencies {		
    implementation 'jp.hituzi:kamome:5.3.4'
}

Manual Installation

  1. Download latest Kamome SDK
  2. Copy kamome.aar to YOUR_ANDROID_STUDIO_PROJECT/app/libs directory
  3. Sync Project in AndroidStudio

Configuration

Timeout to request from the JS code to the native code

KM.send method in JavaScript expects a resolve or reject response will be returned in a duration. If the request is timed out, it's the callback calls reject with the requestTimeout error. You can change default request timeout. See following.

// JavaScript

// Set default timeout in millisecond.
KM.setDefaultRequestTimeout(15000);

If given time is less than or equal to 0, the request timeout function is disabled.

If you want to specify a request timeout individually, you set a timeout in millisecond at KM.send method's 3rd argument.

// JavaScript

// Set a timeout in millisecond at 3rd argument.
const promise = KM.send(commandName, data, 5000);

Optional: console.log for WKWebView on iOS/macOS

The ConsoleLogAdapter class enables to output logs by console.log, console.warn, console.error, and console.assert in JavaScript to Xcode console.

// Swift

ConsoleLogAdapter().setTo(webView)

Use Custom Logger

The ConsoleLogAdapter uses print method to output a log by default. If you use your custom logger, you implement ConsoleLoggable protocol. See following code.

// Swift

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let consoleLogAdapter = ConsoleLogAdapter()
        // Set the custom logger.
        consoleLogAdapter.logger = self
        consoleLogAdapter.setTo(webView)
    }
}

// Implement ConsoleLoggable protocol.
extension ViewController: ConsoleLoggable {
    public func consoleLog(_ logMessage: Any) {
        // TODO: Output a `logMessage` with the custom logger.
    }
}

Browser Alone

When there is no Kamome's iOS/Android native client, that is, when you run with a browser alone, you can register the processing of each command.

// JavaScript

KM.browser
    .addCommand("echo", function (data, resolve, reject) {
        // Received `echo` command.
        // Then sends resolved result to the JavaScript callback function.
        resolve({ message: data["message"] });
        // Or, sends rejected result if failed.
        //reject("Echo Error!");
    });

Sample App

More info, see my iOS sample project and Android sample project.

View on GitHub
GitHub Stars40
CategoryDevelopment
Updated1y ago
Forks7

Languages

Swift

Security Score

87/100

Audited on Mar 31, 2025

No findings