JSPatch icon indicating copy to clipboard operation
JSPatch copied to clipboard

用JSPatch 实现添加JSContext无效!

Open Nihility-Ming opened this issue 8 years ago • 12 comments

我测试过无数次,用用JSPatch 实现Objective-C原生的JSContext无效!

并且,WebView已经正常初始化了,不存在任何问题。self.context()也能console.log()出内存地址!

我写的代码如下:

defineClass('ActionViewController', {
    webViewDidFinishLoad: function(webView) {

        self.ORIGwebViewDidFinishLoad(webView);

        var weakSelf = __weak(self);

        self.context().setObject_forKeyedSubscript(block(function() {
            dispatch_async_main(function(){
                var vc = SPOfferHomeViewController.viewController();
                weakSelf.navigationController().pushViewController_animated(vc, 1);
            });
        }), "openCustomOffer");

        self.context().setObject_forKeyedSubscript(block(function() {
            dispatch_async_main(function(){
                var vc = SPMarketCenterViewController.viewController();
                weakSelf.navigationController().pushViewController_animated(vc, 1);
            });
        }), "openMarketCenter");

    }
});

Nihility-Ming avatar Aug 07 '16 14:08 Nihility-Ming

试试用这个 https://github.com/bang590/JSPatch/wiki/performSelectorInOC-%E4%BD%BF%E7%94%A8%E6%96%87%E6%A1%A3

bang590 avatar Aug 07 '16 14:08 bang590

听了您的意见,我改成了这样:

defineClass('ActionViewController', {
    webViewDidFinishLoad: function(webView) {

        self.ORIGwebViewDidFinishLoad(webView);

        var weakSelf = __weak(self);

        var b1 = block(function() {
            dispatch_async_main(function(){
                var vc = SPOfferHomeViewController.viewController();
                weakSelf.navigationController().pushViewController_animated(vc, 1);
            });
        });

        return self.context().performSelectorInOC('setObject:forKeyedSubscript:', [b1, "openCustomOffer"], function() {

            var b2 = block(function() {
                dispatch_async_main(function(){
                    var vc = SPMarketCenterViewController.viewController();
                    weakSelf.navigationController().pushViewController_animated(vc, 1);
                });
            });

            return weakSelf.context().performSelectorInOC('setObject:forKeyedSubscript:', [b2, "openMarketCenter"], function() {});

        });
    }
});

但是非常遗憾的是,还是不行?请指教

Nihility-Ming avatar Aug 07 '16 15:08 Nihility-Ming

试试self.context()也改成用performSelectorInOC,里面那个也是

bang590 avatar Aug 07 '16 15:08 bang590

defineClass('ActionViewController', {
    webViewDidFinishLoad: function(webView) {

        self.ORIGwebViewDidFinishLoad(webView);

        var weakSelf = __weak(self);

        return self.performSelectorInOC('context', [], function(con) {
            var b1 = block(function() {
                dispatch_async_main(function(){
                    var vc = SPOfferHomeViewController.viewController();
                    weakSelf.navigationController().pushViewController_animated(vc, 1);
                });
            });

            return con.performSelectorInOC('setObject:forKeyedSubscript:', [b1, "openCustomOffer"], function() {

                var b2 = block(function() {
                    dispatch_async_main(function(){
                        var vc = SPMarketCenterViewController.viewController();
                        weakSelf.navigationController().pushViewController_animated(vc, 1);
                    });
                });

                return con.performSelectorInOC('setObject:forKeyedSubscript:', [b2, "openMarketCenter"], function() {});

            });

        });

    }
});

也是不行噢...😢

Nihility-Ming avatar Aug 07 '16 15:08 Nihility-Ming

哪一步开始不行呢?调试下

bang590 avatar Aug 07 '16 15:08 bang590

用WEB检查器调试过,没有任何语法异常,主要就是不走Block里面的内容,也就是设置JSContext (setObject:forKeyedSubscript:)无效...

Nihility-Ming avatar Aug 08 '16 01:08 Nihility-Ming

setObject:forKeyedSubscript:传非block有效吗

bang590 avatar Aug 08 '16 02:08 bang590

传非Block?总之就是无法响应那个Object了,我试着传递一个字符串对象,还是没有根据Key来响应Object。

以下的代码OC正常,我翻译成JSPatch语法则不行...

    __weak __typeof(self) weakSelf = self;
    [self.context setObject:^{
        dispatch_async(dispatch_get_main_queue(), ^{
            SPOfferHomeViewController *vc = [SPOfferHomeViewController viewController];
            [weakSelf.navigationController pushViewController:vc animated:YES];
        });
    } forKeyedSubscript:@"openCustomOffer"];

    [self.context setObject:^{
        dispatch_async(dispatch_get_main_queue(), ^{
            SPMarketCenterViewController *vc = [SPMarketCenterViewController viewController];
            [weakSelf.navigationController pushViewController:vc animated:YES];
        });
    } forKeyedSubscript:@"openMarketCenter"];

Nihility-Ming avatar Aug 08 '16 02:08 Nihility-Ming

大神可以试着写一个简单的Demo噢,可能这个问题还能写入WIKI呢...

Nihility-Ming avatar Aug 08 '16 02:08 Nihility-Ming

@Nihility-Ming @bang590 看了你们的讨论,我试着做了一下,发现这样可以实现。

===oc代码====

#import <JSPatch/JPEngine.h>

typedef void(^JSBridgeBlock)(id p0,id p1,id p2,id p3,id p4,id p5,id p6,id p7,id p8,id p9);

@interface MYJSContext :JSContext

@end @implementation MYJSContext

-(void)setObject:(id)object forKeyedSubscript:(NSObject<NSCopying> *)key{

JSBridgeBlock evalFunc = object;

JSBridgeBlock callBack = ^(id p0,id p1,id p2,id p3,id p4,id p5,id p6,id p7,id p8,id p9){

    evalFunc(p0,p1,p2,p3,p4,p5,p6,p7,p8,p9);

};
[super setObject:callBack forKeyedSubscript:key];

}

@end

@interface ViewController ()<UIWebViewDelegate> @property (strong, nonatomic) UIWebView *webview; @property (strong, nonatomic) MYJSContext *context; @end

@implementation ViewController

  • (void)viewDidLoad { [super viewDidLoad];

    self.context = [[MYJSContext alloc] init]; self.context.exceptionHandler = ^(JSContext *con, JSValue *exception) { NSLog(@"%@", exception);

    }; } -(UIWebView*)webview{ if (!_webview) { _webview = [[UIWebView alloc] initWithFrame:self.view.bounds]; _webview.delegate = self; [self.view addSubview:_webview];

    } return _webview; } -(void)viewDidAppear:(BOOL)animated{ [super viewDidAppear:animated];

    NSURL* url = [NSURL URLWithString:@"http://www.baidu.com"]; [self.webview loadRequest:[NSURLRequest requestWithURL:url]]; }

-(void)webViewDidFinishLoad:(UIWebView )webView{ JSValue value = [self.context objectForKeyedSubscript:@"fromjspatch"]; if (value) { [value callWithArguments:@[@[@1,@2,@3],@"3",@"2"]]; } }

@end

====js代码==

defineClass('ViewController', {

        viewDidLoad:function(){

            self.ORIGviewDidLoad();

            var b1 = block("NSArray*,NSString*,NSString*",function(a,b,c) {
                                console.log("from jspatch count:    " + a.count() + "   b: "  + b.toJS() + "    c: " + c.toJS());


                           });

            return self.performSelectorInOC('context', [], function(context) {

                        return context.performSelectorInOC('setObject:forKeyedSubscript:', [b1, "fromjspatch"], function() {});


            });

        }

})

但我不清楚为什么在-(void)setObject:(id)object forKeyedSubscript:(NSObject<NSCopying> *)key这个方法里用block重新包一下就正常了,你们如果知道还请解释一下。

action121 avatar Aug 09 '16 01:08 action121

我也遇到了类似的问题在JSContext 里面设置的block 没有回调.不过我发现 是这个 [context setObject:@"" forKeyedSubscript:^() {}];没有起到效果

billxie1988 avatar Nov 09 '16 11:11 billxie1988

这个问题解决了吗?我也遇到了这个问题,除了@action121 要增加一个包装类的方法

hellovoidworld avatar Jan 10 '17 05:01 hellovoidworld