I have a JSExport
protocol named ChannelExport
with the method - (void)sendRequest:(NSDictionary *)request withCallback:(JSValue *)callback;
. Calling this method from Javascript code works alright, like this:
channel.sendRequestWithCallback({'foo': 'bar'}, function(response) { ... });
In ObjC, I can access the values in the request
dictionary and also call the callback
function.
Now I'd like to change the interface to - (void)sendRequest:(NSDictionary *)request
, passing the JS function as part of the request
dictionary, like this:
channel.sendRequestWithCallback({
'foo': 'bar'
'callback': function(response) { ... }
});
In this case, when I try to call the callback
function in ObjC, the app crashes. Apparently the callback
object is not a JSValue
, but instead an NSDictionary
(to be more precise, an __NSDictionaryM
). I was assuming that the JS function is correctly wrapped as JSValue
in the same way as it is when passing it as a simple parameter.
Any hint why this is happening, and how to solve the issue?
You can't use - (void)sendRequest:(NSDictionary *)request
signature to achieve your goal. If you define argument as NSDictionary
, JavaScriptCore will recursively convert all objects in this dictionary to corresponding Objective-C objects. Use - (void)sendRequest:(JSValue *)requestValue
instead:
- (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];
}