Giter Site home page Giter Site logo

wendux / dsbridge-ios Goto Github PK

View Code? Open in Web Editor NEW
1.9K 45.0 299.0 2.69 MB

:earth_asia: A modern cross-platform JavaScript bridge, through which you can invoke each other's functions synchronously or asynchronously between JavaScript and native.

Objective-C 74.82% HTML 10.21% Ruby 13.40% Swift 1.25% C 0.22% Shell 0.09%
javascript-bridge jsbridge webviewjavascriptbridge

dsbridge-ios's Introduction

English| 中文简体

DSBridge for IOS

dsBridge

cocoapods MIT Licence support platform GitHub last commit

Modern cross-platform JavaScript bridge, through which you can invoke each other's functions synchronously or asynchronously between JavaScript and native applications.

DSBridge-Android:https://github.com/wendux/DSBridge-Android

Notice

DSBridge 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 >=v3.0.

DSBridge v3.0.0 change list

Features

  1. The three ends of Android, IOS and Javascript are easy to use, light and powerful, safe and strong

  2. Both synchronous and asynchronous calls are supported

  3. Support API Object, which centrally implements APIs in a Java Class or a Javascript object

  4. Support API namespace

  5. Support debug mode

  6. Support the test of whether API exists

  7. Support Progress Callback: one call, multiple returns

  8. Support event listener for Javascript to close the page

  9. Support Modal and Modeless popup box for javascript

  10. Support the X5 webcore of Tencent for Android

Installation

pod "dsBridge"

Examples

See the dsbridgedemo/ package. run the app project and to see it in action.

To use a dsBridge in your own project:

Usage

  1. Implement APIs in a class

    #import "dsbridge.h" 
    ...
    @implementation JsApiTest
    //for synchronous invocation  
    - (NSString *) testSyn:(NSString *) msg
    {
        return [msg stringByAppendingString:@"[ syn call]"];
    }
    //for asynchronous invocation
    - (void) testAsyn:(NSString *) msg :(JSCallback)completionHandler
    {
        completionHandler([msg stringByAppendingString:@" [ asyn call]"],YES);
    }
    @end 
  2. add API object to DWKWebView

    DWKWebView * dwebview=[[DWKWebView alloc] initWithFrame:bounds];
    // register api object without namespace
    [dwebview addJavascriptObject:[[JsApiTest alloc] init] namespace:nil];
  3. Call Native (Java/Object-c/swift) API in Javascript, and register javascript API 。

    • Init dsBridge

      //cdn
      //<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/dsbridge.js"> //</script>
      //npm
      //npm install [email protected]
      var dsBridge=require("dsbridge")
    • Call Native API and register a javascript API for Native invocation

      //Call synchronously 
      var str=dsBridge.call("testSyn","testSyn");
      
      //Call asynchronously
      dsBridge.call("testAsyn","testAsyn", function (v) {
        alert(v);
      })
      
      //Register javascript API for Native
       dsBridge.register('addValue',function(l,r){
           return l+r;
       })
  4. Call Javascript API in Object-C

    [dwebview callHandler:@"addValue" arguments:@[@3,@4] completionHandler:^(NSNumber* value){
            NSLog(@"%@",value);
    }];

Object-C API signature

In order to be compatible with IOS , we make the following convention on Object-C API signature:

  1. For synchronous API.

    (id) handler:(id) msg

    • The argument type can be any class type, but the type of return value can't be void.
  2. For asynchronous API.

    (void) handler:(id) arg :(JSCallback)completionHandler)

    JSCallback is a block type:

    typedef void (^JSCallback)(NSString * _Nullable result,BOOL complete); 

    Attention: API name can't start with "init", because it is reserved in OC class.

Using in Swift

In Swift, you should declare APIs as follows:

//MUST USE "_" to ignore the first argument name explicitly。
@objc func testSyn( _ arg:String) -> String {
	return String(format:"%@[Swift sync call:%@]", arg, "test")
}

@objc func testAsyn( _ arg:String, handler: (String, Bool)->Void) {
	handler(String(format:"%@[Swift async call:%@]", arg, "test"), true)
}

Two points you should keep in mind:

  • Must add "@objc" to Swift API.
  • Must use "_" to ignore the first argument name explicitly

The complete example is here .

Namespace

Namespaces can help you better manage your APIs, which is very useful in hybrid applications, because these applications have a large number of APIs. DSBridge (>= v3.0.0) allows you to classify API with namespace. And the namespace can be multilevel, between different levels with '.' division.

Debug mode

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. You can open debug mode :

// open debug mode
[dwebview setDebugMode:true];

Progress Callback

Normally, 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:

In Object-c

- ( void )callProgress:(NSDictionary *) args :(JSCallback)completionHandler
{
    value=10;
    hanlder=completionHandler;
    timer =  [NSTimer scheduledTimerWithTimeInterval:1.0
                                              target:self
                                            selector:@selector(onTimer:)
                                            userInfo:nil
                                             repeats:YES];
}
-(void)onTimer:t{
    if(value!=-1){
        hanlder([NSNumber numberWithInt:value--],NO);
    }else{
        hanlder(@"",YES);
        [timer invalidate];
    }
}

In Javascript

dsBridge.call("callProgress", function (value) {
    document.getElementById("progress").innerText = value
})

For the complete sample code, please refer to the demo project.

Javascript popup box

For 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.

Note That the default dialog box implemented by DSBridge is modal. This will block the UI thread. If you need modeless, please refer to disableJavascriptDialogBlock.

WKUIDelegate

In DWKWebView , please use DSUIDelegate instead of UIDelegate , because UIDelegate has already been set inner DWKWebView , DSUIDelegate is a proxy of UIDelegate .

API Reference

Object-C API

In Object-c, the object that implements the javascript interfaces is called Object-c API object.

addJavascriptObject:(id) object namespace:(NSString *) namespace

Add the Object-c API object with supplied namespace into DWKWebView. The javascript can then call OC APIs with bridge.call("namespace.api",...).

If the namespace is empty, the Object-c API object have no namespace. The javascript can call OC APIs with bridge.call("api",...).

Example:

In Object-c

@implementation JsEchoApi
- (id) syn:(id) arg
{
    return arg;
}
- (void) asyn: (id) arg :(JSCallback)completionHandler
{
    completionHandler(arg,YES);
}
@end
// register api object with namespace "echo"
[dwebview addJavascriptObject:[[JsEchoApi alloc] init] namespace:@"echo"];

In Javascript

// call echo.syn
var ret=dsBridge.call("echo.syn",{msg:" I am echoSyn call", tag:1})
alert(JSON.stringify(ret))  
// call echo.asyn
dsBridge.call("echo.asyn",{msg:" I am echoAsyn call",tag:2},function (ret) {
      alert(JSON.stringify(ret));
})
removeJavascriptObject:(NSString *) namespace

Remove the Object-c API object with supplied namespace.

callHandler:(NSString *) methodName arguments:(NSArray *) args
callHandler:(NSString *) methodName completionHandler:(void (^)(id value))completionHandler
callHandler:(NSString *) methodName arguments:(NSArray *) args completionHandler:(void (^ )(id value))completionHandler

Call 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.

Example:

[dwebview callHandler:@"append" arguments:@[@"I",@"love",@"you"]
  completionHandler:^(NSString * _Nullable value) {
       NSLog(@"call succeed, append string is: %@",value);
}];
// call with namespace 'syn', More details to see the Demo project                    
[dwebview callHandler:@"syn.getInfo" completionHandler:^(NSDictionary * _Nullable value) {
        NSLog(@"Namespace syn.getInfo: %@",value);
}];
disableJavascriptDialogBlock:(bool) disable

BE 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).

Example:

[dwebview disableJavascriptDialogBlock: true]

if you want to enable the block, just calling this method with the argument value false .

setJavascriptCloseWindowListener:(void(^_Nullable)(void))callback

DWKWebView calls callback when Javascript calls window.close, you can provide a block to add your hanlder .

Example:

[dwebview setJavascriptCloseWindowListener:^{
        NSLog(@"window.close called");
}];
hasJavascriptMethod:(NSString*) handlerName methodExistCallback:(void(^)(bool exist))callback

Test whether the handler exist in javascript.

Example:

// test if javascript method exists.
[dwebview hasJavascriptMethod:@"addValue" methodExistCallback:^(bool exist) {
      NSLog(@"method 'addValue' exist : %d",exist);
}];
setDebugMode:(bool) debug

Set 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.

customJavascriptDialogLabelTitles:(NSDictionary*) dic

custom the label text of javascript dialog that includes alert/confirm/prompt, the default text language is Chinese.

Example:

[dwebview customJavascriptDialogLabelTitles:@{
 @"alertTitle":@"Notification",
 @"alertBtn":@"OK",
 @"confirmTitle":@"",
 @"confirmCancelBtn":@"CANCEL",
 @"confirmOkBtn":@"OK",
 @"promptCancelBtn":@"CANCEL",
 @"promptOkBtn":@"OK"
}];

Javascript API

dsBridge

"dsBridge" is accessed after dsBridge Initialization .

dsBridge.call(method,[arg,callback])

Call Java api synchronously and asynchronously。

method: Java API name, can contain the namespace。

arg: argument, Only one allowed, if you expect multiple parameters, you can pass them with a json object.

callback(String returnValue): callback to handle the result. only asynchronous invocation required.

dsBridge.register(methodName|namespace,function|synApiObject)
dsBridge.registerAsyn(methodName|namespace,function|asyApiObject)

Register javascript synchronous and asynchronous API for Native invocation. There are two types of invocation

  1. Just register a method. For example:

    In Javascript

    dsBridge.register('addValue',function(l,r){
         return l+r;
    })
    dsBridge.registerAsyn('append',function(arg1,arg2,arg3,responseCallback){
         responseCallback(arg1+" "+arg2+" "+arg3);
    })

    In Object-c

    // call javascript method
    [dwebview callHandler:@"addValue" arguments:@[@3,@4] completionHandler:^(NSNumber * value){
          NSLog(@"%@",value);
    }];
    
    [dwebview callHandler:@"append" arguments:@[@"I",@"love",@"you"] completionHandler:^(NSString * _Nullable value) {
         NSLog(@"call succeed, append string is: %@",value);
    }];

  2. Register a Javascript API object with supplied namespace. For example:

    In Javascript

    //namespace test for synchronous
    dsBridge.register("test",{
      tag:"test",
      test1:function(){
    	return this.tag+"1"
      },
      test2:function(){
    	return this.tag+"2"
      }
    })
      
    //namespace test1 for asynchronous calls  
    dsBridge.registerAsyn("test1",{
      tag:"test1",
      test1:function(responseCallback){
    	return responseCallback(this.tag+"1")
      },
      test2:function(responseCallback){
    	return responseCallback(this.tag+"2")
      }
    })

    Because JavaScript does not support function overloading, it is not possible to define asynchronous function and sync function of the same name。

    In Object-c

    [dwebview callHandler:@"test.test1" completionHandler:^(NSString * _Nullable value) {
            NSLog(@"Namespace test.test1: %@",value);
    }];
    
    [dwebview callHandler:@"test1.test1" completionHandler:^(NSString * _Nullable value) {
            NSLog(@"Namespace test1.test1: %@",value);
    }];
dsBridge.hasNativeMethod(handlerName,[type])

Test whether the handler exist in Java, the handlerName can contain the namespace.

type: optional["all"|"syn"|"asyn" ], default is "all".

dsBridge.hasNativeMethod('testAsyn') 
//test namespace method
dsBridge.hasNativeMethod('test.testAsyn')
// test if exist a asynchronous function that named "testSyn"
dsBridge.hasNativeMethod('testSyn','asyn') //false
dsBridge.disableJavascriptDialogBlock(disable)

Calling dsBridge.disableJavascriptDialogBlock(...) has the same effect as calling disableJavascriptDialogBlock in Java.

Example:

//disable
dsBridge.disableJavascriptDialogBlock()
//enable
dsBridge.disableJavascriptDialogBlock(false)

Work with fly.js

As 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 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.

Another typical scene is in the hybrid App, Fly.js 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.

More details please refer to https://github.com/wendux/fly.

Finally

If you like DSBridge, please star to let more people know it , Thank you !

dsbridge-ios's People

Contributors

dodohua avatar l1dan avatar wendux avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dsbridge-ios's Issues

2.0改了什么呢?

2.0了改了什么,能不能说一下呢?
还有目前你这个设计,不支持以下下场景
原生多次返回结果
因为每次返回结果后,把桥接对象就删除了。

iOS 11.1.2 使用DWKWebView加载网页时,TIC Read Status [1:0x1c016f3c0]: 1:57

TIC Read Status [1:0x1c016f3c0]: 1:57
NSURLConnection finished with error - code -1001
APIBase request didFailWithError
NSURLConnection finished with error - code -1001
APIBase request didFailWithError
NSURLConnection finished with error - code -1001
APIBase request didFailWithError
Task <40F5571F-D735-41A0-BDFE-5EEEA51B1847>.<0> HTTP load failed (error code: -999 [1:89])

getJsBridge= undefined

在ios中. 访问服务端网页 getJsBridge 获取为undefined, 但是将网页放在本地就可以获取到.

WKWebView下JS调用原生方法, 方法的定位不准

发现dsbridge里面有个小问题 就是如果一个方法名和另一个方法名是包含关系并且长的方法名在前边会出现方法执行错误问题

代码如下

- (NSString *)testSyn123123:(NSString *) msg
{
    return [msg stringByAppendingString:@"[ syn call]"];
}

- (NSString *)testSyn:(NSString *) msg
{
    return [msg stringByAppendingString:@"[ syn call]"];
}

这时在js中调用testSyn方法就会跳到testSyn123123方法上

解决方法如下 修改一下方法判断依据 代码没怎么读 也没进行啥测试 如果有遇到此问题的人可以改改 不过具体还需要作者本人测试 如果有问题随时找我 = =

+ (NSString *)methodByNameArg:(NSInteger)argNum selName:(NSString *)selName class:(Class)class {
    NSString *result = nil;
    if(class){
        NSArray *arr = [JSBUtil allMethodFromClass:class];
        for (int i = 0; i < arr.count; i++) {
            NSString *method = arr[i];
            NSArray *tmpArr = [method componentsSeparatedByString:@":"];
            NSRange range = [method rangeOfString:@":"];
            if (range.length > 0) {
                NSString *methodName = [method substringWithRange:NSMakeRange(0, range.location)];
                if ([methodName isEqualToString:selName] && tmpArr.count == (argNum + 1)) {
                    result = method;
                    return result;
                }
            }
        }
    }
    return result;
}

请问swift的话端方法如何定义?

这是我的swift的定义

 func testSyn(arg:String) -> String {
       return String(format:"%@[sync call:%@]", "msg", "test")
 }

js调用
alert(this.ds_bridge.call("testSyn","testSyn"))

然后页面alert报错:“Method{"data":"testSyn"} is not invoked, since there is not a implementation for it”

xcode报错:“json解析失败:Error Domain=NSCocoaErrorDomain Code=3840 "JSON text did not start with array or object and option to allow fragments not set." UserInfo={NSDebugDescription=JSON text did not start with array or object and option to allow fragments not set.}”

我是vue搭配dsbridge,swift4,ios11

最后问一下,3.0是否不支持UIWebview,目前依赖于Vassonic提升加载速度,可是后者不支持wkwebview,3.0是否有再次支持UIWebview的可能?

iOS9出现大量奔溃

-> translating『 0x41c2cb 』=> -> translating『 0xa8a59 』=> +[JSBUtil call::JavascriptInterfaceObject:jscontext:] -> translating『 0x2a141 』=> -[DWKwebview webView:runJavaScriptTextInputPanelWithPrompt:defaultText:initiatedByFrame:completionHandler:] -> translating『 0x2aae5 』=> main

当服务器返回为JSON字符串,且回掉方法为Void的时候,程序会闪退

JavascriptInterfaceObject调用的方法返回值为void,且服务器传参为Json字符串时会闪退.

修改test.html代码为如下

function callSyn() {
        alert(dsBridge.call("testSyn", "{\"url\":\"https://gslb.miaopai.com/stream/U8wK~SkowQqfbmyHNhFyDH0vy-KhqWvmdQMHLQ__.mp4?ssig=f3c7cac4c571591cc1b4c1da917a6ea2&amp;time_stamp=1526013092137&amp;cookie_id=c90730d82972cf7f169f2d7d246fc6a9&amp;vend=1&amp;os=2&amp;partner=1&amp;platform=2&amp;cookie_id=c90730d82972cf7f169f2d7d246fc6a9&amp;refer=miaopai&amp;scid=U8wK%7ESkowQqfbmyHNhFyDH0vy-KhqWvmdQMHLQ__\"}"))
    }

修改JsApiTest.m代码如下

- (void) testSyn:(NSString *) msg
{
//    return [msg stringByAppendingString:@"[ syn call]"];
    NSLog(@"%@",@"call");
}

编译不通过

cocoapods集成

DUIwebview里WebEventDelegate,JavascriptInterfaceObject;这两个变量
提示Cannot sysnthesize weak property because the current deployment target does not support weak references

关于DUIwebView的时候内存暴涨不释放

一直用的DUIwebView.一开始没发现2个问题.(1)在不退出页面的时候操作的时候内存一直涨 能涨到1个G不释放,目前测试加载任何网页 都有这种问题. (2)我检测内存 发现退出页面内存没有改变 在+(NSArray *)allMethodFromClass:(Class)class 中的Method *methods = class_copyMethodList(class, &count) 没有释放 我free(methods)之后 稍微有改观 但是效果不明显

使用DSBridge必须集成DWebView吗

我的项目是集成UIWebView的,并且自己做了很多处理,现在不太可能修改集成DWebView,请问如果要使用DSJsBright必须使用DWebView吗?是否提供WebView的Category来实现DWebView功能,降低使用门槛?

How to synchronize cookie between native and DWKWebView ?

There are two ways to do this:

  1. With JavaScript

    NSString * script=@"document.cookie=\"uname=xx; uid=34\"";
    [dwebview evaluateJavaScript:script completionHandler:nil];
  2. With fly.js

    Actually, fly.js can't support synchronizing Cookies between native and DWKWebView, but it supports forwarding the http request to Native through any Javascript bridge, and fly.js has already provide the dsBridge adapter. Suppose that all HTTP requests will be sent out on native side, there's no longer need to sync Cookies to DWKWebView. all you need to do is implementing a API named onAjaxRequest in default API namespace :

    /**
     * Note: This method is for Fly.js
     * In browser, Ajax requests are sent by browser, but Fly can
     * redirect requests to native, more about Fly see  https://github.com/wendux/fly
     * @param requestInfo passed by fly.js, more detail reference https://wendux.github.io/dist/#/doc/flyio-en/native
     */
    -(void)onAjaxRequest:(NSDictionary *) requestInfo  :(void (^)(NSString * _Nullable result,BOOL complete))completionHandle{
       
    }

    More details please refer to:

    1. https://wendux.github.io/dist/#/doc/flyio-en/redirect
    2. https://wendux.github.io/dist/#/doc/flyio-en/native

Swift中同步的没问题,异步的一直报Method is not invoked ,已经检查过版本,web的是^3.1.3,iOS的是3.0.2

iOS端
class AntzbJsBridgeabc: NSObject {

@objc func testSyn(args:Dictionary<String,Any>) -> String {
    let msg = args["msg"] as? String ?? ""
    return String(format:"%@[sync call:%@]", msg, "test")
}

@objc func testAsyn(arg:String, handler: (String, Bool)->Void) {
    handler(String(format:"%@[async call:%@]", arg, "test"), true)
}

}

webview.addJavascriptObject(AntzbJsBridgeabc(), namespace: "abc")

Web端

this.msg = dsbridge.call("abc.testSyn", {a:"aa",b:12,msg:"asasas"}) //没问题

dsBridge.call("abc.testAsyn",'sassas', function (name) {//有问题,报Method is not invoked的错
this.msg = name
alert(name)
})

方法名的匹配逻辑有问题。

例如在同一个jsBridge中实现了 request和requestWithData,如果前端调用了request,但是requestWithData的定义比requst早,则实际调用的方法是requestWithData,因为源码中方法匹配的逻辑是根据方法前缀以及参数个数来匹配的,有漏洞。建议根据方法的signature来匹配。
方法匹配逻辑在JSBUtil.m文件 方法methodByNameArg:selName:class: 中。

Load HTML string crash in Swift

我在swift项目里使用dsBridge,用cocoapods集成。然后添加DWebview

var webView = DWebview()

override func viewDidLoad() {
        super.viewDidLoad()
        self.webView.frame = self.view.bounds
        self.view.addSubview(self.webView)
        let jsApi = JsApiHandler()
        self.webView.javascriptInterfaceObject = jsApi
    }

    func loadHTML(_ html: String, baseURL: URL?) {
        self.webView.loadHTMLString(html, baseURL: baseURL ?? URL(string: "*")!)
    }

业务需要后端返回的是一个HTML字符串,然后用WebView显示这个页面。

因为该库用OC写的,而原生UIWebView的loadHTMLString方法的baseURL参数是可选参数,DWebView暴露的接口参数没有支持nullable,所以这里就必须填写一个非nil的baseURL,这样要么crash,要么黑屏。

希望接口能支持Swift友好的nullable协议。

补充:单独使用DUIWebView或者DWKWebView使用loadHTMLString方法baseURL为nil运行正常。

debug模式崩溃

-[__NSCFNumber length]: unrecognized selector sent to instance 0xb0000000000000b3
invalid mode 'kCFRunLoopCommonModes' provided to CFRunLoopRunSpecific - break on _CFRunLoopError_RunCalledWithInvalidMode to debug. This message will only appear once per execution.

demo中并不能实现JS端异步调用原生方法

步骤:
在JsApiTest定义JS异步调用的方法中加入阻塞线程代码,比如

- (void) testAsyn:(NSDictionary *) args :(void (^)(NSString * _Nullable result,BOOL complete))completionHandler
{
    sleep(5);
    completionHandler([(NSString *)[args valueForKey:@"msg"] stringByAppendingString:@"[ asyn call]"],YES);
}

test.html js端加上log日志

function callAsyn() {
        console.log("callAsyn beigin")
        bridge.call("testAsyn", {msg: "testAsyn"}, function (v) {
                    alert(v)
                })
        console.log("callAsyn end")
    }

在js端调用 程序时序是这样的

console.log("callAsyn beigin")
等待五秒
alert(v)
console.log("callAsyn end")

可以看出这并不是异步调用

真机会闪退?

你好,我想麻烦问一下.我这边相同的代码在模拟器里面能正常跑,但是在真机里就会出现闪退的情况.

参数问题

DKWebView 中有使用namespace 参数 能不能改一下名字,因为在c ++ 中是关键字,混编有问题。
JSBUtil 中有个参数是 class ,这样也有问题

v3.0 change list

DSBridge v3.0 change list

DSBridge v3.0 is a milestone, Compared with v2.0.X, 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 >=v3.0

In Java

  1. DeprecatedsetJavascriptInterface , use addJavascriptObject instead.

  2. DeprecatedsetJavascriptContextInitedListener ,callHandler can be called at any time.

  3. DeprecatedDUIWebView , UIWebView will not be supported ever.

  4. New: addJavascriptObject:(id) object namespace:(NSString *) namespace

  5. New: removeJavascriptObject:NSString * namespace

  6. New: disableJavascriptDialogBlock:(bool) disable

  7. New: hasJavascriptMethod:(NSString *) handlerName methodExistCallback:(void(^ )(bool exist))callback

  8. New: setJavascriptCloseWindowListener:(void(^)(void))callback

  9. New: setDebugMode:(bool) debug

  10. New: customJavascriptDialogLabelTitles:(NSDictionary*) dic

  11. New feature: Support namespace

  12. New feature: Can add multiple API object

  13. Changed: Object-c API signature changed

  14. Changed: callHandler can be called at any time.

In Javascript

  1. New: hasNativeMethod(handlerName,[type])
  2. New: disableJavascriptDialogBlock(disable)
  3. New: registerAsyn(methodName|namespace,function|asyApiObject)
  4. Changed: register(methodName|namespace,function|synApiObject)
  5. New feature: Support namespace

Why Only Support WKWebView?

Advantages of WKWebView

It is well known that WKWebView loads web pages faster and more efficiently than UIWebView, and also doesn't have as much memory overhead for you.

Under the current timeline, most iOS apps only support iOS 9.0+.

UIWebView Cross-Domain Access Vulnerability

The reason for the iOS platform cross-domain access vulnerability is due to UIWebView turning on the WebKitAllowUniversalAccessFromFileURLs and WebKitAllowFileAccessFromFileURLs options.

WKWebView default allowFileAccessFromFileURLs and allowUniversalAccessFromFileURLs option is false.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.