{"id":21921229,"url":"https://github.com/alexaubry/JavaScriptKit","last_synced_at":"2025-07-21T20:31:08.043Z","repository":{"id":56916926,"uuid":"101650666","full_name":"alexaubry/JavaScriptKit","owner":"alexaubry","description":"JavaScript Toolkit for WKWebView","archived":false,"fork":false,"pushed_at":"2019-03-02T15:15:51.000Z","size":1457,"stargazers_count":87,"open_issues_count":0,"forks_count":6,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-07-15T06:25:51.848Z","etag":null,"topics":["ios","javascript","macos","swift","webkit","wkwebview-js"],"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/alexaubry.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-08-28T14:18:35.000Z","updated_at":"2025-05-07T03:33:55.000Z","dependencies_parsed_at":"2022-08-20T21:20:28.092Z","dependency_job_id":null,"html_url":"https://github.com/alexaubry/JavaScriptKit","commit_stats":null,"previous_names":["alexaubry/javascriptkit"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/alexaubry/JavaScriptKit","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexaubry%2FJavaScriptKit","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexaubry%2FJavaScriptKit/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexaubry%2FJavaScriptKit/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexaubry%2FJavaScriptKit/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/alexaubry","download_url":"https://codeload.github.com/alexaubry/JavaScriptKit/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/alexaubry%2FJavaScriptKit/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266375049,"owners_count":23919509,"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","status":"online","status_checked_at":"2025-07-21T11:47:31.412Z","response_time":64,"last_error":null,"robots_txt_status":null,"robots_txt_updated_at":null,"robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["ios","javascript","macos","swift","webkit","wkwebview-js"],"created_at":"2024-11-28T20:19:54.808Z","updated_at":"2025-07-21T20:31:07.689Z","avatar_url":"https://github.com/alexaubry.png","language":"Swift","readme":"# JavaScriptKit\n\n[![Build Status](https://dev.azure.com/alexaubry/JavaScriptKit/_apis/build/status/alexaubry.JavaScriptKit?branchName=master)](https://dev.azure.com/alexaubry/JavaScriptKit/_build/latest?definitionId=4?branchName=master)[![Version](https://img.shields.io/cocoapods/v/JavaScriptKit.svg?style=flat)](http://cocoapods.org/pods/JavaScriptKit)\n[![License](https://img.shields.io/cocoapods/l/JavaScriptKit.svg?style=flat)](http://cocoapods.org/pods/JavaScriptKit)\n[![Platform](https://img.shields.io/cocoapods/p/JavaScriptKit.svg?style=flat)](http://cocoapods.org/pods/JavaScriptKit)\n\nJavaScriptKit is a powerful replacement for JavaScriptCore to use with your WebKit web views. Supports iOS and macOS.\n\n## Features\n\n- Generate and evaluate type-safe JavaScript expressions in WKWebView\n- Automatically encode and decode values, JSON objects and enumerations to and from JavaScript\n- Easy error handling\n- [Documented](https://alexaubry.github.io/JavaScriptKit)\n\n## Installation\n\n### CocoaPods\n\nTo use CocoaPods, add the following to your Podfile:\n\n```ruby\npod 'JavaScriptKit', '~\u003e 2.0'\n```\n\n### Carthage\n\nTo use Carthage, add the following to your Cartfile:\n\n```ogdl\ngithub \"alexaubry/JavaScriptKit\" ~\u003e 2.0\n```\n## Versions\n\n| | 1.0.x | 2.0.x |\n|---|---|---|\n| Minimum iOS Version | 8.0 | 8.0 |\n| Minimum macOS Version | 10.10 | 10.10 |\n| Supported Swift Version(s) | 4.0.x | 4.2.x |\n\n## How it works\n\nThe library is structured around the `JSExpression` protocol. Expressions can be represented as a JavaScript expression string, and have their return type defined at compile-time for better type safety.\n\nYou can evaluate expressions inside of a `WKWebView`. You provide a callback block that will be called with a `Result` object, containing either the value returned on success, or the error thrown by the web view on failure. Callback blocks are always executed on the main thread.\n\nWhen the web view returns the result, `JavaScriptKit` uses a custom [`Decoder`](https://developer.apple.com/documentation/swift/decoder) to decode it into the return type you specified. This allows you to set the return type to any [`Decodable`](https://developer.apple.com/documentation/swift/decodable) type (structures, classes, primitive types, enumeration, array, dictionary, ...).\n\n## Usage\n\n### Get the value of a variable\n\nUse the `JSVariable` expression type to get the value of a variable at the specified key path.\n\n#### Example 1.1\n\n\u003e Get the title of the current document\n\n~~~swift\nlet titleVariable = JSVariable\u003cString\u003e(\"document.title\")\n\nwebView.evaluate(expression: titleVariable) { result in\n    switch result {\n    case .success(let title):\n        // do something with the `title` string\n\n    case .failure(let error):\n        // handle error\n    }\n}\n~~~\n\n- The `title` value provided on success is a `String`.\n\n### Call a function\n\nUse the `JSFunction` expression type to call a function at the specified key path. You can pass as many arguments as needed. They must conform to the `Encodable` protocol to be converted to a JavaScript representation.\n\nWhen the function does not return a value, use the `JSVoid` return type.\n\n#### Example 2.1\n\n\u003e URI-Encode a String\n\n~~~swift\nlet encodeURI = JSFunction\u003cString\u003e(\"window.encodeURI\", arguments: \"Hello world\")\n\nwebView.evaluate(expression: encodeURI) { result in\n    switch result {\n    case .success(let encodedURI):\n        // do something with the `encodedURI` string\n\n    case .failure(let error):\n        // handle error\n    }\n}\n~~~\n\n- The `alert` expression will be converted to: `\"this.window.encodeURI(\"Hello world\");\"`.\n- The `encodedURI` value provided on success is a `String`.\n\n#### Example 2.2\n\n\u003e Show an alert\n\n~~~swift\nlet alert = JSFunction\u003cJSVoid\u003e(\"window.alert\", arguments: \"Hello from Swift!\")\nwebView.evaluate(expression: alert, completionHandler: nil)\n~~~\n\n- The `alert` expression will be converted to: `\"this.window.alert(\"Hello from Swift!\");\"`.\n- To ignore the result of the expression, pass `nil` for the `completionHandler` argument.\n\n#### Example 2.3\n\n\u003e Reload the window\n\n~~~swift\nlet reload = JSFunction\u003cJSVoid\u003e(\"location.reload\")\n\nwebView.evaluate(expression: reload, completionHandler: nil)\n~~~\n\n- You can omit the `arguments` parameter if the function takes no arguments.\n\n### Run your custom scripts\n\nUse the `JSScript` expression type to run your custom scripts. To create custom scripts, you define a `String` that contains the script to run and define the return value.\n\nThe last evaluated statement in your script will be used as the return value. Do not use `return` at the end of the script, as it would yield an invalid value.\n\n#### Example 3.1\n\n\u003e Get the time of the day from a time string in the document\n\n~~~swift\nenum TimeOfDay: String, Decodable {\n    case night, morning, afternoon, evening\n}\n\nlet scriptBody = \"\"\"\nfunction getTimeOfDay(hour) {\n\n    if (hour \u003e= 0 \u0026\u0026 hour \u003c 6) {\n        return \"night\";\n    } else if (hour \u003e= 6 \u0026\u0026 hour \u003c 12) {\n        return \"morning\"\n    } else if (hour \u003e= 12 \u0026\u0026 hour \u003c 18) {\n        return \"afternoon\"\n    } else if (hour \u003e= 18 \u0026\u0026 hour \u003e 0) {\n        return \"evening\"\n    }\n\n}\n\nvar postPublishDate = document.getElementById(\"publish-date\").innerHTML\nvar hours = new Date(postPublishDate).getHours();\n\ngetTimeOfDay(hours);\n\"\"\"\n\nlet script = JSScript\u003cTimeOfDay\u003e(scriptBody)\n\nwebView.evaluate(expression: script) { result in\n\n    switch result {\n    case .success(let timeOfDay):\n        // do something with the `timeOfDay` object\n\n    case .failure(let error):\n        // handle error\n    }\n\n}\n~~~\n\n- The `timeOfDay` value provided on success is a case of `TimeOfDay`.\n- `TimeOfDay` is a supported return type because it implements the `Decodable` protocol.\n\n## Contributing\n\nContributions are welcome and appreciated! Here's how you should submit contributions:\n\n- Fork and clone the repository\n- Create a new branch for your fixes (ex: `git checkout -b [your branch name]`)\n- Get the development dependencies by running `carthage bootstrap`\n- Add your changes and commit them to your branch\n- Submit a PR to the `master` branch\n\nIf you find a bug or think a feature is missing, please [submit an issue](https://github.com/alexaubry/JavaScriptKit/issues).\n\n## Authors\n\nAlexis Aubry, me@alexaubry.fr \u003c[@_alexaubry](https://twitter.com/_alexaubry)\u003e\n\n## License\n\nJavaScriptKit is available under the MIT license. See the [LICENSE](LICENSE) file for more info.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexaubry%2FJavaScriptKit","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Falexaubry%2FJavaScriptKit","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Falexaubry%2FJavaScriptKit/lists"}