{"id":20294172,"url":"https://github.com/grab/mobile-kit-bridge-sdk","last_synced_at":"2025-04-11T11:42:51.325Z","repository":{"id":48017911,"uuid":"184014846","full_name":"grab/mobile-kit-bridge-sdk","owner":"grab","description":"SDK for web view bridges that offers unified method signatures for Android/iOS","archived":false,"fork":false,"pushed_at":"2023-06-12T05:38:08.000Z","size":699,"stargazers_count":7,"open_issues_count":6,"forks_count":5,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-25T08:03:21.462Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"TypeScript","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/grab.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","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":"2019-04-29T06:43:39.000Z","updated_at":"2021-07-20T05:35:47.000Z","dependencies_parsed_at":"2024-06-19T11:13:53.166Z","dependency_job_id":"3eecf205-84f2-483a-b74b-7ea2cd0ff20b","html_url":"https://github.com/grab/mobile-kit-bridge-sdk","commit_stats":{"total_commits":131,"total_committers":2,"mean_commits":65.5,"dds":0.007633587786259555,"last_synced_commit":"46c902d984cb51617094f3a0cf7d8c2aa1fa56b6"},"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grab%2Fmobile-kit-bridge-sdk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grab%2Fmobile-kit-bridge-sdk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grab%2Fmobile-kit-bridge-sdk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/grab%2Fmobile-kit-bridge-sdk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/grab","download_url":"https://codeload.github.com/grab/mobile-kit-bridge-sdk/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248385968,"owners_count":21094982,"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":[],"created_at":"2024-11-14T15:28:07.869Z","updated_at":"2025-04-11T11:42:51.305Z","avatar_url":"https://github.com/grab.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Disclaimer\n\nThis SDK is a generic SDK for native webviews. For Grab `SuperApp` integration, please use the [SuperApp SDK](https://github.com/grab/superapp-sdk).\n\n# mobile-kit-bridge-sdk\n\nSDK for mobile module bridge to offer unified method signatures for Android/iOS.\n\n## Asynchronous returns\n\nFor example:\n\n```javascript\nconst identifier = await window.WrappedLocaleKit.invoke(\"getLocaleIdentifier\");\nawait window.WrappedAnalyticsModule.invoke(\"track\", { analyticsEvent: event });\nawait window.WrappedMediaKit.invoke(\"playDRMContent\", { contentURL, license });\n```\n\nAll module methods will have `callback` as one of the parameters:\n\n```java\nclass AnalyticsModuleBridge {\n  fun track(requestString: String) {\n    val request = Gson().fromJson(...)\n    val callback = request.callback\n    ...\n  }\n}\n```\n\n```swift\nfinal class AnalyticsModuleBridge: WKScriptMessageHandler {\n  func userContentController(\n    _ userContentController: WKUserContentController,\n    didReceive message: WKScriptMessage) {\n    let request = message.body as! [String : Any]\n    let callback = request[\"callback\"] as! String\n    ...\n  }\n}\n```\n\nFor the sake of standardization, **all** module methods must invoke the relevant callback after they finish, even if they run synchronously or do not have anything meaningful to return. Use the parameter `callback` to identify the correct callback to invoke:\n\n```java\nwebView.evaluateJavascript(\"javascript:window.$callback(...)\") { _ -\u003e }\n```\n\n```swift\nwebView.evaluateJavascript(\"window.\\(callback)(...)\", nil)\n```\n\nThe name of the callback always starts with:\n\n```javascript\n[moduleName]_[functionName]Callback\n```\n\nFor e.g.:\n\n```javascript\nAnalyticsModule.track -\u003e WrappedAnalyticsModule_trackCallback\nMediaKit.playDRMContent -\u003e WrappedMediaKit_playDRMContentCallback\n```\n\nThis callback style allows us to pass errors to the partner app that they can handle in case something goes wrong.\n\n## Value streaming\n\nAll module methods return streams, e.g.:\n\n```javascript\n/** Get stream of location updates. */\nconst subscription = window.WrappedLocationModule.invoke(\n  \"observeLocationChange\"\n).subscribe({ next: console.log, complete: console.log });\n```\n\nCalling these methods returns `DataStream` objects that can be subscribed to with `StreamHandlers` (i.e. `onValue`, `onComplete` etc.). Once `subscribe` is called, a `Subscription` object is created to control when streaming should be terminated.\n\nNote that `DataStream` always creates new streams whenever `subscribe` is called, so there is no need to worry about invoking it multiple times. The concept of `DataStream` is similar to that of an `Observable`, and it is easy to bridge the two:\n\n```javascript\nconst playObservable = new Observable(sub =\u003e {\n  const subscription = window.WrappedMediaKit.invoke('observePlayDRMContent', { isStream: true, ... }).subscribe({\n    next: data =\u003e sub.next(data),\n    complete: () =\u003e sub.complete(),\n  });\n\n  return () =\u003e subscription.unsubscribe();\n});\n\nplayObservable.pipe(filter(...), map(...)).subscribe(...);\n```\n\n`DataStream` also supports `Promise`-style chaining and `async-await`. Instead of getting values over time, this will simply deliver the first value that arrives:\n\n```javascript\nconst { result, error, status_code } = await window.WrappedMediaKit.invoke('observePlayDRMContent', { isStream: true, ... });\n```\n\nPlease be aware that **Promises returned by bridged methods are non-eager**, so they will only be triggered on invocation of `then`, or after an `await` in an `async` function.\n\n## Data format\n\nCallback results must be in the format prescribed below:\n\n```javascript\ntype CallbackResult\u003cT = unknown\u003e = Readonly\u003c{\n  /** The result of the operation. */\n  result: T,\n\n  /** The error object, if any. */\n  error: unknown,\n\n  /** The status code. */\n  status_code: number\n}\u003e;\n```\n\nMake sure native code is passing data in the correct format, or else callbacks will not be invoked.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgrab%2Fmobile-kit-bridge-sdk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgrab%2Fmobile-kit-bridge-sdk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgrab%2Fmobile-kit-bridge-sdk/lists"}