{"id":21089770,"url":"https://github.com/hituziando/kamome","last_synced_at":"2025-04-28T13:32:17.123Z","repository":{"id":37250709,"uuid":"150767320","full_name":"HituziANDO/kamome","owner":"HituziANDO","description":"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.","archived":false,"fork":false,"pushed_at":"2024-10-13T07:32:27.000Z","size":8114,"stargazers_count":35,"open_issues_count":4,"forks_count":6,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-11-20T10:20:10.955Z","etag":null,"topics":["android","cross-platform","ios","javascript","macos","webview","wkwebview"],"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/HituziANDO.png","metadata":{"files":{"readme":"README.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-09-28T16:29:17.000Z","updated_at":"2024-08-22T02:22:13.000Z","dependencies_parsed_at":"2024-11-19T21:41:50.553Z","dependency_job_id":null,"html_url":"https://github.com/HituziANDO/kamome","commit_stats":{"total_commits":196,"total_committers":2,"mean_commits":98.0,"dds":"0.26530612244897955","last_synced_commit":"f891227c3193251c7968afa61aa0ba4e8d04f809"},"previous_names":[],"tags_count":26,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HituziANDO%2Fkamome","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HituziANDO%2Fkamome/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HituziANDO%2Fkamome/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/HituziANDO%2Fkamome/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/HituziANDO","download_url":"https://codeload.github.com/HituziANDO/kamome/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251319786,"owners_count":21570456,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["android","cross-platform","ios","javascript","macos","webview","wkwebview"],"created_at":"2024-11-19T21:31:17.645Z","updated_at":"2025-04-28T13:32:17.074Z","avatar_url":"https://github.com/HituziANDO.png","language":"Swift","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Kamome\n\n![release](https://img.shields.io/github/v/release/HituziANDO/kamome?display_name=tag)\n[![npm](https://img.shields.io/npm/v/kamome)](https://www.npmjs.com/package/kamome)\n[![Pod Version](https://img.shields.io/cocoapods/v/kamome.svg?style=flat)](http://cocoapods.org/pods/kamome)\n[![Carthage Compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)\n[![Swift Package Manager compatible](https://img.shields.io/badge/Swift%20Package%20Manager-compatible-brightgreen.svg)](https://github.com/apple/swift-package-manager)\n\nKamome 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.\n\n\u003cimg src=\"./README/images/illustration.png\" width=\"410\"\u003e\n\nKamome provides common JavaScript interface for iOS and Android.\n\nIf you build Flutter apps with the WebView, see [kamome_flutter](https://github.com/HituziANDO/kamome_flutter) for the Flutter plugin.\n\n## Quick Usage\n\n### Sends a message from the JS code to the native code\n\n1. Sends a message from the JavaScript code\n\t\n\t```javascript\n\t// JavaScript\n\n\timport { KM } from \"kamome\"\n\n\t// Uses async/await.\n\ttry {\n\t    // Sends `echo` command.\n\t    const result = await KM.send('echo', { message: 'Hello' });\n\t    // Receives a result from the native code if succeeded.\n\t    console.log(result.message);\n\t} catch(error) {\n\t    // Receives an error from the native code if failed.\n\t    console.log(error);\n\t}\n\t```\n\n1. Receives a message on iOS\n\t\n\t```swift\n\t// Swift\n\n\tprivate lazy var webView: WKWebView = {\n\t    let webView = WKWebView(frame: self.view.frame)\n\t    return webView\n\t}()\n\n\tprivate var client: Client!\n\n\toverride func viewDidLoad() {\n\t    super.viewDidLoad()\n\n\t    // Creates the Client object with the webView.\n\t    client = Client(webView)\n\n\t    // Registers `echo` command.\n\t    client.add(Command(\"echo\") { commandName, data, completion in\n\t        // Received `echo` command.\n\t        // Then sends resolved result to the JavaScript callback function.\n\t        completion.resolve([\"message\": data![\"message\"]!])\n\t        // Or, sends rejected result if failed.\n\t        //completion.reject(\"Echo Error!\")\n\t    })\n\n\t    let htmlURL = Bundle.main.url(forResource: \"index\", withExtension: \"html\", subdirectory: \"www\")!\n\t    webView.loadFileURL(htmlURL, allowingReadAccessTo: htmlURL)\n\t    view.addSubview(webView)\n\t}\n\t```\n\n\t**[NOTE]** This framework supports WKWebView only. UIWebView is not supported.\n\t\n1. Receives a message on Android\n\t\n\t```kotlin\n\t// Kotlin\n\n\tprivate var client: Client? = null\n\n\toverride fun onCreate(savedInstanceState: Bundle?) {\n       super.onCreate(savedInstanceState)\n       setContentView(R.layout.activity_main)\n\n       val webView = findViewById\u003cWebView\u003e(R.id.webView)\n\n       // Creates the Client object with the webView.\n       client = Client(webView)\n\n       // Registers `echo` command.\n       client.add(Command(\"echo\") { commandName, data, completion -\u003e\n           // Received `echo` command.\n           // Then sends resolved result to the JavaScript callback function.\n           val map = HashMap\u003cString?, Any?\u003e()\n           map[\"message\"] = data!!.optString(\"message\")\n           completion.resolve(map)\n           // Or, sends rejected result if failed.\n           //completion.reject(\"Echo Error!\")\n       })\n\n       webView.loadUrl(\"file:///android_asset/www/index.html\")\n   }\n\t```\n\n### Sends a message from the native code to the JS code\n\n1. Sends a message from the native code on iOS\n\t\n\t```swift\n\t// Swift\n\t\n\t// Send a data to the JS code.\n\tclient.send([\"greeting\": \"Hello! by Swift\"], commandName: \"greeting\") { (commandName, result, error) in\n\t    // Received a result from the JS code.\n\t    guard let result = result else { return }\n\t    print(\"result: \\(result)\")\n\t}\n\t```\n\n1. Sends a message from the native code on Android\n\t\n\t```kotlin\n\t// Kotlin\n\t\n\t// Sends a data to the JS code.\n\tval data = HashMap\u003cString?, Any?\u003e()\n   data[\"greeting\"] = \"Hello! by Kotlin\"\n   client?.send(data, \"greeting\") { commandName, result, error -\u003e\n       // Received a result from the JS code.\n       Log.d(TAG, \"result: $result\")\n   }\n\t```\n\n1. Receives a message on the JavaScript code\n\t\n\t```javascript\n\t// JavaScript\n\t\n\t// Adds a receiver that receives a message sent by the native client.\n\tKM.addReceiver('greeting', (data, resolve, reject) =\u003e {\n\t    // The data is the object sent by the native client.\n\t    console.log(data.greeting);\n\n\t    // Runs asynchronous something to do...\n\t    setTimeout(() =\u003e {\n\n\t        // Returns a result as any object or null to the native client.\n\t        resolve('OK!');\n\t        // If the task is failed, call `reject()` function.\n\t        //reject('Error message');\n\t    }, 1000);\n\t});\n\t```\n\n## Include Library in Your Project\n\n### 1. JavaScript\n\n#### npm\n\n1. npm install\n\t\n\t```\n\tnpm install kamome\n\t```\n\n1. Write following import statement in JavaScript\n\t\n\t```javascript\n\timport { KM } from \"kamome\"\n\t```\n\t\n#### Manual Installation\n\n1. Download latest [Kamome SDK](https://github.com/HituziANDO/kamome/releases)\n1. Import kamome.umd.js\n\t\n\t```html\n\t\u003cscript src=\"/path/to/kamome.umd.js\"\u003e\u003c/script\u003e\n\t\u003cscript\u003e\n\t  const KM = window.Kamome.KM;\n\t\u003c/script\u003e\n\t```\n\n### 2. iOS App\n\n#### Swift Package Manager\n\nKamome is available through Swift Package Manager. To install it using Xcode, specify the git URL for Kamome.\n\t\n\t\n```\nhttps://github.com/HituziANDO/kamome.git\n```\n\n#### CocoaPods\n\t\nKamome is available through [CocoaPods](http://cocoapods.org). To install it, simply add the following line to your Podfile:\n\t\n```ruby\npod \"kamome\"\n```\n\n#### Carthage\n\nKamome is available through [Carthage](https://github.com/Carthage/Carthage). To install it, simply add the following line to your Cartfile:\n\n```\ngithub \"HituziANDO/kamome\"\n```\n\nYou run the following command in the Terminal.\n\n```\ncarthage update --use-xcframeworks\n```\n\n#### Manual Installation\n\n1. Download latest [Kamome SDK](https://github.com/HituziANDO/kamome/releases)\n1. Drag \u0026 drop kamome.xcframework into your Xcode project\n1. Click General tab in your target\n1. In Frameworks, Libraries, and Embedded Content, Select \"Embed \u0026 Sign\" for kamome.xcframework\n\n#### Import Framework\n\nWrite the import statement in your source code\n\n```swift\nimport kamome\n```\n\n### 3. Android App\n\n#### Gradle\n\nAdd the following code in build.gradle(project level).\n\n```groovy\nallprojects {\n    repositories {\n        maven {\n            url 'https://hituziando.github.io/kamome/android/repo'\n        }\n    }\n}\n```\n\nAdd the following code in build.gradle(app level).\n\n```groovy\ndependencies {\t\t\n    implementation 'jp.hituzi:kamome:5.3.4'\n}\n```\n\n#### Manual Installation\n\n1. Download latest [Kamome SDK](https://github.com/HituziANDO/kamome/releases)\n1. Copy kamome.aar to YOUR\\_ANDROID\\_STUDIO\\_PROJECT/app/libs directory\n1. Sync Project in AndroidStudio\n\n## Configuration\n\n### Timeout to request from the JS code to the native code\n\n`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.\n\n```javascript\n// JavaScript\n\n// Set default timeout in millisecond.\nKM.setDefaultRequestTimeout(15000);\n```\n\nIf given time is less than or equal to 0, the request timeout function is disabled.\n\nIf you want to specify a request timeout individually, you set a timeout in millisecond at `KM.send` method's 3rd argument.\n\n```javascript\n// JavaScript\n\n// Set a timeout in millisecond at 3rd argument.\nconst promise = KM.send(commandName, data, 5000);\n```\n\n## Optional: console.log for WKWebView on iOS/macOS\n\nThe `ConsoleLogAdapter` class enables to output logs by `console.log`, `console.warn`, `console.error`, and `console.assert` in JavaScript to Xcode console.\n\n```swift\n// Swift\n\nConsoleLogAdapter().setTo(webView)\n```\n\n### Use Custom Logger\n\nThe ConsoleLogAdapter uses `print` method to output a log by default. If you use your custom logger, you implement `ConsoleLoggable` protocol. See following code.\n\n```swift\n// Swift\n\nclass ViewController: UIViewController {\n\n    override func viewDidLoad() {\n        super.viewDidLoad()\n\n        let consoleLogAdapter = ConsoleLogAdapter()\n        // Set the custom logger.\n        consoleLogAdapter.logger = self\n        consoleLogAdapter.setTo(webView)\n    }\n}\n\n// Implement ConsoleLoggable protocol.\nextension ViewController: ConsoleLoggable {\n    public func consoleLog(_ logMessage: Any) {\n        // TODO: Output a `logMessage` with the custom logger.\n    }\n}\n```\n\n## Browser Alone\n\nWhen 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.\n\n```javascript\n// JavaScript\n\nKM.browser\n    .addCommand(\"echo\", function (data, resolve, reject) {\n        // Received `echo` command.\n        // Then sends resolved result to the JavaScript callback function.\n        resolve({ message: data[\"message\"] });\n        // Or, sends rejected result if failed.\n        //reject(\"Echo Error!\");\n    });\n```\n\n## Sample App\n\nMore info, see my [iOS sample project](https://github.com/HituziANDO/kamome/tree/main/ios) and [Android sample project](https://github.com/HituziANDO/kamome/tree/main/android).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhituziando%2Fkamome","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhituziando%2Fkamome","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhituziando%2Fkamome/lists"}