如何将 JS 函数作为对象 属性 传递给 iOS

How to pass a JS function as object property to iOS

我有一个名为 ChannelExportJSExport 协议,方法为 - (void)sendRequest:(NSDictionary *)request withCallback:(JSValue *)callback;。从 Javascript 代码调用此方法工作正常,如下所示:

channel.sendRequestWithCallback({'foo': 'bar'}, function(response) { ... });

在 ObjC 中,我可以访问 request 字典中的值,还可以调用 callback 函数。

现在我想将接口更改为 - (void)sendRequest:(NSDictionary *)request,将 JS 函数作为 request 字典的一部分传递,如下所示:

channel.sendRequestWithCallback({
  'foo': 'bar'
  'callback': function(response) { ... }
});

在这种情况下,当我尝试调用 ObjC 中的 callback 函数时,应用程序崩溃了。显然 callback 对象不是 JSValue,而是 NSDictionary(更准确地说,是 __NSDictionaryM)。我假设 JS 函数被正确包装为 JSValue,就像将它作为简单参数传递时一样。

任何提示为什么会发生这种情况,以及如何解决这个问题?

您不能使用 - (void)sendRequest:(NSDictionary *)request 签名来实现您的目标。如果将参数定义为 NSDictionary,JavaScriptCore 将递归地将此字典中的所有对象转换为相应的 Objective-C 对象。使用 - (void)sendRequest:(JSValue *)requestValue 代替:

- (void)sendRequest:(JSValue *)requestValue {
    JSValue *fooJSValue = [requestValue valueForProperty:@"foo"];
    NSString *bar = [fooJSValue isUndefined] ? nil : fooValue.toString;
    // use bar

    JSValue *callback = [requestValue valueForProperty:@"callback"];
    [callback callWithArguments:myArguments];
}