{"id":13509396,"url":"https://github.com/wendux/DSBridge-IOS","last_synced_at":"2025-03-30T13:32:08.116Z","repository":{"id":41385203,"uuid":"77835887","full_name":"wendux/DSBridge-IOS","owner":"wendux","description":":earth_asia: A modern cross-platform JavaScript bridge, through which you can invoke each other's functions synchronously or asynchronously between JavaScript and native.","archived":false,"fork":false,"pushed_at":"2023-02-22T08:37:56.000Z","size":2753,"stargazers_count":1983,"open_issues_count":68,"forks_count":312,"subscribers_count":46,"default_branch":"master","last_synced_at":"2025-03-23T22:12:19.241Z","etag":null,"topics":["javascript-bridge","jsbridge","webviewjavascriptbridge"],"latest_commit_sha":null,"homepage":"","language":"Objective-C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wendux.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2017-01-02T13:37:58.000Z","updated_at":"2025-03-05T10:04:55.000Z","dependencies_parsed_at":"2024-01-13T20:40:21.011Z","dependency_job_id":"40449881-7459-4a34-b932-7eefec5ff452","html_url":"https://github.com/wendux/DSBridge-IOS","commit_stats":{"total_commits":67,"total_committers":6,"mean_commits":"11.166666666666666","dds":0.582089552238806,"last_synced_commit":"f0e3c724dd362800528f8b6c788bdad7006cc187"},"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wendux%2FDSBridge-IOS","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wendux%2FDSBridge-IOS/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wendux%2FDSBridge-IOS/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wendux%2FDSBridge-IOS/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wendux","download_url":"https://codeload.github.com/wendux/DSBridge-IOS/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246323997,"owners_count":20759059,"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":["javascript-bridge","jsbridge","webviewjavascriptbridge"],"created_at":"2024-08-01T02:01:07.189Z","updated_at":"2025-03-30T13:32:07.651Z","avatar_url":"https://github.com/wendux.png","language":"Objective-C","readme":"English| [中文简体](https://github.com/wendux/DSBridge-IOS/blob/master/readme-chs.md)   \n# DSBridge  for  IOS\n\n![dsBridge](https://github.com/wendux/DSBridge-IOS/raw/master/img/dsbridge.png)\n\n\n[![cocoapods](https://img.shields.io/cocoapods/v/dsBridge.svg?style=flat)](https://github.com/wendux/DSBridge-IOS)  ![](https://img.shields.io/badge/language-object--c-yellow.svg) [![](https://travis-ci.org/wendux/DSBridge-IOS.svg?branch=master)](https://travis-ci.org/wendux/DSBridge-IOS) [![MIT Licence](https://img.shields.io/packagist/l/doctrine/orm.svg)](https://opensource.org/licenses/mit-license.php)  ![support](https://img.shields.io/badge/support-IOS%208%2B-green.svg) ![platform](https://img.shields.io/badge/platform-ios|osx-ff69b4.svg) [![GitHub last commit](https://img.shields.io/github/last-commit/wendux/DSBridge-IOS.svg?color=blue)](https://github.com/wendux/DSBridge-IOS/) \n\n\n\u003e Modern cross-platform JavaScript bridge, through which you can invoke each other's functions synchronously or asynchronously between JavaScript and native applications.\n\n   \nDSBridge-Android：https://github.com/wendux/DSBridge-Android \n\n\n### Notice\n\nDSBridge v3.0 is a milestone version. Compared with v2.0, we have made a lot of changes. Note that v3.0 is **incompatible** with v2.0, but v2.0 will continue to maintain. If you are a new user, use \u003e=v3.0.\n\n[DSBridge v3.0.0 change list](https://github.com/wendux/DSBridge-IOS/issues/25)  \n\n\n\n## Features\n\n1. The three ends of Android, IOS and Javascript are easy to use, light and powerful, safe and strong\n\n2. Both synchronous and asynchronous calls are supported\n\n3. Support **API Object**, which centrally implements  APIs in a Java Class or a Javascript object \n\n4. Support API namespace\n\n5. Support debug mode\n\n6. Support the test of whether API exists\n\n7. Support **Progress Callback**: one call, multiple returns\n\n8. Support event listener for Javascript to close the page\n\n9. Support Modal and Modeless popup box for javascript\n\n10. Support the X5 webcore of Tencent  for Android\n\n  ​\n\n## Installation\n\n```shell\npod \"dsBridge\"\n```\n\n\n\n## Examples\n\nSee the `dsbridgedemo/` package. run the `app` project and to see it in action.\n\nTo use a dsBridge in your own project:\n\n\n\n## Usage\n\n1. Implement APIs in a class \n\n   ```objective-c\n   #import \"dsbridge.h\" \n   ...\n   @implementation JsApiTest\n   //for synchronous invocation  \n   - (NSString *) testSyn:(NSString *) msg\n   {\n       return [msg stringByAppendingString:@\"[ syn call]\"];\n   }\n   //for asynchronous invocation\n   - (void) testAsyn:(NSString *) msg :(JSCallback)completionHandler\n   {\n       completionHandler([msg stringByAppendingString:@\" [ asyn call]\"],YES);\n   }\n   @end \n   ```\n\n2. add API object to DWKWebView \n\n   ```objective-c\n   DWKWebView * dwebview=[[DWKWebView alloc] initWithFrame:bounds];\n   // register api object without namespace\n   [dwebview addJavascriptObject:[[JsApiTest alloc] init] namespace:nil];\n   ```\n\n3. Call Native (Java/Object-c/swift) API in Javascript, and register  javascript API 。\n\n   - Init dsBridge\n\n     ```javascript\n     //cdn\n     //\u003cscript src=\"https://cdn.jsdelivr.net/npm/dsbridge@3.1.4/dist/dsbridge.js\"\u003e //\u003c/script\u003e\n     //npm\n     //npm install dsbridge@3.1.4\n     var dsBridge=require(\"dsbridge\")\n     ```\n\n   - Call Native API and register a javascript API for Native invocation\n\n     ```javascript\n\n     //Call synchronously \n     var str=dsBridge.call(\"testSyn\",\"testSyn\");\n\n     //Call asynchronously\n     dsBridge.call(\"testAsyn\",\"testAsyn\", function (v) {\n       alert(v);\n     })\n\n     //Register javascript API for Native\n      dsBridge.register('addValue',function(l,r){\n          return l+r;\n      })\n     ```\n\n4. Call Javascript API in Object-C\n\n   ```objective-c\n   [dwebview callHandler:@\"addValue\" arguments:@[@3,@4] completionHandler:^(NSNumber* value){\n           NSLog(@\"%@\",value);\n   }];\n   ```\n\n\n\n\n## Object-C API signature\n\nIn order to be compatible with IOS , we make the following convention  on Object-C API signature:\n\n1. For synchronous API.\n\n   **`(id) handler:(id) msg`**\n\n   -  The argument type can be any class  type, but  the type of return value can't be  **void**.\n\n2. For asynchronous API.\n\n     **` (void) handler:(id) arg :(JSCallback)completionHandler）`**\n\n     `JSCallback` is a block type:\n\n     ```objective-c\n     typedef void (^JSCallback)(NSString * _Nullable result,BOOL complete); \n     ```\n\n   \u003e Attention: API name can't start with \"init\", because it is reserved in OC class.\n\n## Using in Swift\n\nIn Swift, you should declare APIs as follows:\n\n```swift\n//MUST USE \"_\" to ignore the first argument name explicitly。\n@objc func testSyn( _ arg:String) -\u003e String {\n\treturn String(format:\"%@[Swift sync call:%@]\", arg, \"test\")\n}\n\n@objc func testAsyn( _ arg:String, handler: (String, Bool)-\u003eVoid) {\n\thandler(String(format:\"%@[Swift async call:%@]\", arg, \"test\"), true)\n}\n```\n\nTwo points you should keep in mind:\n\n- Must add \"@objc\" to Swift API.\n- Must  use \"_\"  to ignore the first argument name explicitly\n\nThe complete example is [here](https://github.com/wendux/DSBridge-IOS/blob/master/dsbridgedemo/JsApiTestSwift.swift) .\n\n## Namespace\n\nNamespaces can help you better manage your APIs, which is very useful in   hybrid applications, because these applications have a large number of APIs. DSBridge (\u003e= v3.0.0) allows you to classify API with namespace. And the namespace can be multilevel, between different levels with '.' division.\n\n## Debug mode\n\nIn debug mode, some errors will be prompted by a popup dialog , and the exception caused by the native APIs will not be captured to expose problems. We recommend that the debug mode be opened at the development stage.  You can open debug mode :\n\n```objective-c\n// open debug mode\n[dwebview setDebugMode:true];\n```\n\n\n\n## Progress Callback\n\nNormally, when a API is called to end, it returns a result, which corresponds one by one. But sometimes a call need to repeatedly return multipule times,  Suppose that on the Native side, there is  a API to download the file, in the process of downloading, it will send the progress information to  Javascript  many times, then Javascript will  display  the progress information on the H5 page. Oh...You will find it is difficult to achieve this function. Fortunately, DSBridge supports **Progress Callback**. You can be very simple and convenient to implement a call that needs to be returned many times. Here's an example of a countdown：\n\nIn Object-c \n\n```objective-c\n- ( void )callProgress:(NSDictionary *) args :(JSCallback)completionHandler\n{\n    value=10;\n    hanlder=completionHandler;\n    timer =  [NSTimer scheduledTimerWithTimeInterval:1.0\n                                              target:self\n                                            selector:@selector(onTimer:)\n                                            userInfo:nil\n                                             repeats:YES];\n}\n-(void)onTimer:t{\n    if(value!=-1){\n        hanlder([NSNumber numberWithInt:value--],NO);\n    }else{\n        hanlder(@\"\",YES);\n        [timer invalidate];\n    }\n}\n```\n\nIn Javascript\n\n```javascript\ndsBridge.call(\"callProgress\", function (value) {\n    document.getElementById(\"progress\").innerText = value\n})\n```\n\nFor the complete sample code, please refer to the demo project.\n\n\n\n## Javascript popup box\n\nFor Javascript popup box functions (alert/confirm/prompt), DSBridge has implemented them  all  by default. the default dialog label text language is Chinese, you can custom the text by calling `customJavascriptDialogLabelTitles`.  If you still want to implement them by yourself , set the `DSUIDelegate`  property which is a proxy of `WKUIDelegate`. \n\nNote That the default dialog box  implemented by DSBridge is modal. This will block the UI thread. If you need modeless, please refer to `disableJavascriptDialogBlock`.\n\n\n\n# WKUIDelegate\n\nIn `DWKWebView ` , please use ` DSUIDelegate` instead of `UIDelegate` , because `UIDelegate` has already been set inner  `DWKWebView ` , `DSUIDelegate` is a proxy of `UIDelegate` .\n\n\n\n## API Reference\n\n### Object-C API\n\nIn Object-c, the object that implements the javascript interfaces is called **Object-c API object**.\n\n##### `addJavascriptObject:(id) object namespace:(NSString *) namespace`\n\nAdd the Object-c API object with supplied namespace into DWKWebView. The javascript can then call OC APIs  with `bridge.call(\"namespace.api\",...)`. \n\nIf the namespace is empty, the Object-c API object have no namespace. The javascript can  call OC APIs with `bridge.call(\"api\",...)`. \n\nExample:\n\n**In Object-c**\n\n```objective-c\n@implementation JsEchoApi\n- (id) syn:(id) arg\n{\n    return arg;\n}\n- (void) asyn: (id) arg :(JSCallback)completionHandler\n{\n    completionHandler(arg,YES);\n}\n@end\n// register api object with namespace \"echo\"\n[dwebview addJavascriptObject:[[JsEchoApi alloc] init] namespace:@\"echo\"];\n```\n\n**In Javascript**\n\n```javascript\n// call echo.syn\nvar ret=dsBridge.call(\"echo.syn\",{msg:\" I am echoSyn call\", tag:1})\nalert(JSON.stringify(ret))  \n// call echo.asyn\ndsBridge.call(\"echo.asyn\",{msg:\" I am echoAsyn call\",tag:2},function (ret) {\n      alert(JSON.stringify(ret));\n})\n```\n\n\n\n##### `removeJavascriptObject:(NSString *) namespace`\n\nRemove the  Object-c API object with supplied namespace.\n\n\n\n##### `callHandler:(NSString *) methodName  arguments:(NSArray *) args`\n\n##### `callHandler:(NSString *) methodName  completionHandler:(void (^)(id value))completionHandler`\n\n##### `callHandler:(NSString *) methodName  arguments:(NSArray *) args completionHandler:(void (^ )(id value))completionHandler`\n\nCall the javascript API. If a `completionHandler` is given, the javascript handler can respond. the `methodName` can contain the namespace.  **The completionHandler will be called in main thread**.\n\nExample:\n\n```objective-c\n[dwebview callHandler:@\"append\" arguments:@[@\"I\",@\"love\",@\"you\"]\n  completionHandler:^(NSString * _Nullable value) {\n       NSLog(@\"call succeed, append string is: %@\",value);\n}];\n// call with namespace 'syn', More details to see the Demo project                    \n[dwebview callHandler:@\"syn.getInfo\" completionHandler:^(NSDictionary * _Nullable value) {\n        NSLog(@\"Namespace syn.getInfo: %@\",value);\n}];\n```\n\n\n\n##### `disableJavascriptDialogBlock:(bool) disable`\n\nBE CAREFUL to use. if you call any of the javascript popup box functions (`alert`,` confirm`, and `prompt`), the app will hang, and the javascript execution flow will be blocked. if you don't want to block the javascript execution flow, call this method, the  popup box functions will return  immediately(  `confirm` return `true`, and the `prompt` return empty string).\n\nExample:\n\n```objective-c\n[dwebview disableJavascriptDialogBlock: true]\n```\n\nif you want to  enable the block,  just calling this method with the argument value `false` .\n\n\n\n##### `setJavascriptCloseWindowListener:(void(^_Nullable)(void))callback`\n\nDWKWebView calls `callback` when Javascript calls `window.close`, you can provide a block to add your hanlder .\n\nExample:\n\n```objective-c\n[dwebview setJavascriptCloseWindowListener:^{\n        NSLog(@\"window.close called\");\n}];\n```\n\n\n\n##### `hasJavascriptMethod:(NSString*) handlerName methodExistCallback:(void(^)(bool exist))callback`\n\nTest whether the handler exist in javascript. \n\nExample:\n\n```objective-c\n// test if javascript method exists.\n[dwebview hasJavascriptMethod:@\"addValue\" methodExistCallback:^(bool exist) {\n      NSLog(@\"method 'addValue' exist : %d\",exist);\n}];\n```\n\n\n\n##### `setDebugMode:(bool) debug`\n\nSet debug mode. if in debug mode, some errors will be prompted by a popup dialog , and the exception caused by the native APIs will not be captured to expose problems. We recommend that the debug mode be opened at the development stage. \n\n\n\n##### `customJavascriptDialogLabelTitles:(NSDictionary*) dic`\n\ncustom the  label text of  javascript dialog that includes alert/confirm/prompt, the default text language is Chinese.\n\nExample:\n\n```objective-c\n[dwebview customJavascriptDialogLabelTitles:@{\n @\"alertTitle\":@\"Notification\",\n @\"alertBtn\":@\"OK\",\n @\"confirmTitle\":@\"\",\n @\"confirmCancelBtn\":@\"CANCEL\",\n @\"confirmOkBtn\":@\"OK\",\n @\"promptCancelBtn\":@\"CANCEL\",\n @\"promptOkBtn\":@\"OK\"\n}];\n```\n\n\n\n### Javascript API\n\n##### dsBridge \n\n\"dsBridge\" is accessed after dsBridge Initialization .\n\n\n\n##### `dsBridge.call(method,[arg,callback])`\n\nCall Java api synchronously and asynchronously。\n\n`method`: Java API name， can contain the namespace。\n\n`arg`: argument, Only one  allowed,  if you expect multiple  parameters,  you can pass them with a json object.\n\n`callback(String returnValue)`: callback to handle the result. **only asynchronous invocation required**.\n\n\n\n##### `dsBridge.register(methodName|namespace,function|synApiObject)`\n\n##### `dsBridge.registerAsyn(methodName|namespace,function|asyApiObject)`\n\nRegister javascript synchronous and asynchronous  API for Native invocation. There are two types of invocation\n\n1. Just register a method. For example:\n\n   In Javascript\n\n   ```javascript\n   dsBridge.register('addValue',function(l,r){\n        return l+r;\n   })\n   dsBridge.registerAsyn('append',function(arg1,arg2,arg3,responseCallback){\n        responseCallback(arg1+\" \"+arg2+\" \"+arg3);\n   })\n   ```\n\n   In Object-c\n\n   ```objective-c\n   // call javascript method\n   [dwebview callHandler:@\"addValue\" arguments:@[@3,@4] completionHandler:^(NSNumber * value){\n         NSLog(@\"%@\",value);\n   }];\n\n   [dwebview callHandler:@\"append\" arguments:@[@\"I\",@\"love\",@\"you\"] completionHandler:^(NSString * _Nullable value) {\n        NSLog(@\"call succeed, append string is: %@\",value);\n   }];\n   ```\n\n   ​\n\n2. Register a Javascript API object with supplied namespace. For example:\n\n   **In Javascript**\n\n   ```java\n   //namespace test for synchronous\n   dsBridge.register(\"test\",{\n     tag:\"test\",\n     test1:function(){\n   \treturn this.tag+\"1\"\n     },\n     test2:function(){\n   \treturn this.tag+\"2\"\n     }\n   })\n     \n   //namespace test1 for asynchronous calls  \n   dsBridge.registerAsyn(\"test1\",{\n     tag:\"test1\",\n     test1:function(responseCallback){\n   \treturn responseCallback(this.tag+\"1\")\n     },\n     test2:function(responseCallback){\n   \treturn responseCallback(this.tag+\"2\")\n     }\n   })\n   ```\n\n   \u003e Because JavaScript does not support function overloading, it is not possible to define asynchronous function and sync function of the same name。\n   \u003e\n\n   **In Object-c**\n\n   ```objective-c\n   [dwebview callHandler:@\"test.test1\" completionHandler:^(NSString * _Nullable value) {\n           NSLog(@\"Namespace test.test1: %@\",value);\n   }];\n\n   [dwebview callHandler:@\"test1.test1\" completionHandler:^(NSString * _Nullable value) {\n           NSLog(@\"Namespace test1.test1: %@\",value);\n   }];\n   ```\n\n\n\n\n##### `dsBridge.hasNativeMethod(handlerName,[type])`\n\nTest whether the handler exist in Java, the `handlerName` can contain the namespace. \n\n`type`: optional`[\"all\"|\"syn\"|\"asyn\" ]`, default is \"all\".\n\n```javascript\ndsBridge.hasNativeMethod('testAsyn') \n//test namespace method\ndsBridge.hasNativeMethod('test.testAsyn')\n// test if exist a asynchronous function that named \"testSyn\"\ndsBridge.hasNativeMethod('testSyn','asyn') //false\n```\n\n\n\n##### `dsBridge.disableJavascriptDialogBlock(disable)`\n\nCalling `dsBridge.disableJavascriptDialogBlock(...)` has the same effect as calling ` disableJavascriptDialogBlock` in Java.\n\nExample:\n\n```javascript\n//disable\ndsBridge.disableJavascriptDialogBlock()\n//enable\ndsBridge.disableJavascriptDialogBlock(false)\n```\n\n\n\n## Work with fly.js\n\nAs we all know, In  browser, AJax request are restricted by same-origin policy, so the request cannot be initiated across the domain.  However,    [Fly.js](https://github.com/wendux/fly) supports forwarding the http request  to Native through any Javascript bridge, And fly.js has already provide the dsBridge adapter.Because the  Native side has no the same-origin policy restriction, fly.js can request any resource from any domain. \n\nAnother typical scene is in the hybrid App, [Fly.js](https://github.com/wendux/fly)  will forward all requests to Native, then, the unified request management, cookie management, certificate verification, request filtering and so on are carried out on Native. \n\nMore details please refer to https://github.com/wendux/fly.\n\n## Finally\n\nIf you like DSBridge, please star to let more people know it , Thank you !\n\n\n","funding_links":[],"categories":["Objective-C","HarmonyOS","WebView","Objective-C  Stars 1000以内排名整理"],"sub_categories":["Windows Manager"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwendux%2FDSBridge-IOS","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwendux%2FDSBridge-IOS","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwendux%2FDSBridge-IOS/lists"}