【问题标题】:JavascriptCore: pass javascript function as parameter in JSExportJavascriptCore:在 JSExport 中将 javascript 函数作为参数传递
【发布时间】:2014-03-24 10:45:44
【问题描述】:

JavascriptCore 是 iOS7 支持的新框架。我们可以使用 JSExport 协议将部分 objc 类暴露给 JavaScript。

在 javascript 中,我尝试将函数作为参数传递。就像这样:

function getJsonCallback(json) {
        movie = JSON.parse(json)
        renderTemplate()
}
viewController.getJsonWithURLCallback("", getJsonCallback)

在我的 objc viewController 中,我定义了我的协议:

@protocol FetchJsonForJS <JSExport>
 - (void)getJsonWithURL:(NSString *)URL
               callback:(void (^)(NSString *json))callback;
 - (void)getJsonWithURL:(NSString *)URL
         callbackScript:(NSString *)script;
@end

在 javascript 中,viewController.getJsonWithURLCallbackScript 有效,但是 viewController.getJsonWithURLCallback 无效。

我在 JSExport 中使用 block 有什么错误吗?谢谢。

【问题讨论】:

    标签: javascript ios hybrid-mobile-app javascriptcore


    【解决方案1】:

    问题是您已将回调定义为采用 NSString 参数的 Objective-C 块,但 javascript 不知道如何处理它,并在您尝试评估 viewController.getJsonWithURLCallback("", getJsonCallback) 时产生异常- 它认为第二个参数的类型是'undefined'

    相反,您需要将回调定义为 javascript 函数。

    您可以在 Objective-C 中简单地使用 JSValue 来做到这一点。

    对于其他读者,这是一个完整的工作示例(带有异常处理):

    TestHarnessViewController.h:

    #import <UIKit/UIKit.h>
    #import <JavaScriptCore/JavaScriptCore.h>
    
    @protocol TestHarnessViewControllerExports <JSExport>
    - (void)getJsonWithURL:(NSString *)URL callback:(JSValue *)callback;
    @end
    
    @interface TestHarnessViewController : UIViewController <TestHarnessViewControllerExports>
    @end
    

    TestHarnessViewController.m: (如果使用复制/粘贴,请删除 evaluateScript 中的换行符 - 为清楚起见添加了这些换行符):

    #import "TestHarnessViewController.h"
    
    @implementation TestHarnessViewController {
        JSContext *javascriptContext;
    }
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
    
        javascriptContext  = [[JSContext alloc] init];
        javascriptContext[@"consoleLog"] = ^(NSString *message) {
            NSLog(@"Javascript log: %@",message);
        };
        javascriptContext[@"viewController"] = self;
    
        javascriptContext.exception = nil;
        [javascriptContext evaluateScript:@"
            function getJsonCallback(json) {
                consoleLog(\"getJsonCallback(\"+json+\") invoked.\");
                /* 
                movie = JSON.parse(json); 
                renderTemplate(); 
                */
            } 
    
            viewController.getJsonWithURLCallback(\"\", getJsonCallback);
        "];
        JSValue *e = javascriptContext.exception;
        if (e != nil && ![e isNull])
            NSLog(@"Javascript exception occurred %@", [e toString]);
    }
    
    - (void)getJsonWithURL:(NSString *)URL callback:(JSValue *)callback {
        NSString *json = @""; // Put JSON extract from URL here
        [callback callWithArguments:@[json]];
    }
    
    - (void)didReceiveMemoryWarning
    {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    @end
    

    【讨论】:

    • 在 javascript 调用中执行 getJsonWithURLCallback(\"\", getJsonCallback) - (void)getJsonWithURL:(NSString *)URL callback:(JSValue *)callback 吗?我在使用 JSContext 从 javascript 调用两个参数化函数时遇到问题,请帮忙。
    • @jnix - 对不起,我不明白你的评论。也许你应该发布一个新问题。
    • @Mike 我是说我无法使用 to 参数调用本机 objcC 函数。有关更多详细信息,您可以查看 -stackoverflow.com/questions/22801909/… quetion
    • @jnix - 你上面的评论没有解释你遇到了什么问题(特别是因为示例答案已经适用于两个参数),但是阅读你的另一个问题我看到你已经解决了- 如果涉及多个参数,则通过 JSExport 公开的 ObjC 方法名称已更改,objCMethod:withArgTwo:andArgThree: 在 javascript 中变为 objCMethodWithArgTwoAndArgThree()
    • 这是真的。我是在尝试组合后才知道的:D 感谢您的回复。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多