I'd like to define a function in the JavascriptCore context that takes a variable amount of arguments.
Something like this:
JSVirtualMachine* virtualMachine = [[JSVirtualMachine alloc] init];
JSContext* ctx = [[JSContext alloc] initWithVirtualMachine:virtualMachine];
ctx[@"func"] = ^(JSValue* value, ...){
va_list args;
va_start(args, value);
for (JSValue *arg = value; arg != nil; arg = va_arg(args, JSValue*)) {
NSLog( @"%@", arg);
}
va_end(args);
};
[ctx evaluateScript:@"func('arg1', 'arg2');"];
I believe that the JSC wrapper doesn't pass the second argument to the block, because iterating on va_list
crashes after logging the first argument.
I also tried with the NSArray*
convention, it doesn't work.
Is this possible in any way?
From JSContext.h:
// This method may be called from within an Objective-C block or method invoked
// as a callback from JavaScript to retrieve the callback's arguments, objects
// in the returned array are instances of JSValue. Outside of a callback from
// JavaScript this method will return nil.
+ (NSArray *)currentArguments;
Leading to the following:
ctx[@"func"] = ^{
NSArray *args = [JSContext currentArguments];
for (JSValue *arg in args) {
NSLog( @"%@", arg);
}
};
[ctx evaluateScript:@"func('arg1', 'arg2');"];
I like @erm410's answer, I had not seen the documentation on currentArguments.
Another approach I have taken is to pass a JSON object to an Objective-C NSDictonary. One benefit to this approach is that you have named arguments - though you are dealing with string literals that will need to be typed correctly between the call and the handler.
ctx[@"func"] = ^(NSDictionary *args) {
NSLog(@"%@", args[@"arg1"];
};
[ctx evaluateScript:@"func({'arg1':'first','arg2':'second'})"];
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With