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.
Kamome provides common JavaScript interface for iOS and Android.
If you build Flutter apps with the WebView, see kamome_flutter for the Flutter plugin.
-
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); }
-
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.
-
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 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)") }
-
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") }
-
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); });
-
npm install
npm install kamome
-
Write following import statement in JavaScript
import { KM } from "kamome"
-
Download latest Kamome SDK
-
Import kamome.umd.js
<script src="/path/to/kamome.umd.js"></script> <script> const KM = window.Kamome.KM; </script>
Kamome is available through Swift Package Manager. To install it using Xcode, specify the git URL for Kamome.
https://github.com/HituziANDO/kamome.git
Kamome is available through CocoaPods. To install it, simply add the following line to your Podfile:
pod "kamome"
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
- Download latest Kamome SDK
- Drag & drop kamome.xcframework into your Xcode project
- Click General tab in your target
- In Frameworks, Libraries, and Embedded Content, Select "Embed & Sign" for kamome.xcframework
Write the import statement in your source code
import kamome
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'
}
- Download latest Kamome SDK
- Copy kamome.aar to YOUR_ANDROID_STUDIO_PROJECT/app/libs directory
- Sync Project in AndroidStudio
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);
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)
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.
}
}
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!");
});
More info, see my iOS sample project and Android sample project.