How to execute JSExport Objective-C method with object
I want to write an Objective-C method that can be exported to JavaScript so that I can get a JavaScript object into native code. For example, in the following code: someObject
is the native implemented object and fun is its method.
I know using JSExport
can export native method to JavaScript. and successfully pass the JavaScript string to native code ( NSString*
). But when I want to pass a JavaScript object to native, it fails.
How to solve this?
Thank you so much
source to share
In addition to converting javascript strings to NSString *, as you have already noticed, Javascript objects are copied into a KVC compatible objective-C object (essentially an NSDictionary instance) before being passed to your objective-C method.
For example, with the following definitions:
@protocol MyJSAPI
- (void)fun:(id)param;
@end
@interface MyObject: NSObject<MyJSAPI>
- (void)fun:(id)param;
@end
and initializing your JSContext like this:
myjscontext[@"someObject"] = [[MyObject alloc] init];
[myjscontext evaluateScript:@"someObject.fun({ k : 'value1', k2 : 'value2'});
then your method fun:(id)param
can access fields k
and k2
objects like this:
@implementation MyObject
- (void)fun:(id)param {
NSString* k = [param valueForKey:@"k"];
NSString* k2 = [param valueForKey:@"k2"];
NSLog(@"k = %@, k2 = %@", k, k2);
}
@end
source to share
In addition to ste3veh's answer.
You can use the macro JSExportAs
as follows to export an Objective-C method as one JavaScript:
@interface MyObject: NSObject <JSExport>
JSExportAs(fun,
- (void)fun:(id)param
);
@end
@implementation MyObject
- (void)fun:(id)param {
NSString* k = [param objectForKey:@"k"];
NSString* k2 = [param objectForKey:@"k2"];
NSLog(@"k = %@, k2 = %@", k, k2);
}
@end
In this case, it param
will be implicitly converted to the corresponding Objective-C divlect using -[JSValue toObject]
. In your case, it will be converted to NSDictionary
. To avoid implicit conversion, you can specify the parameter as JSValue
:
@interface MyObject: NSObject <JSExport>
JSExportAs(fun,
- (void)fun:(JSValue*)param
);
@end
@implementation MyObject
- (void)fun:(JSValue*)param {
NSString* k = [[param valueForProperty:@"k"] toString];
NSString* k2 = [[param valueForProperty:@"k2"] toString];
NSLog(@"k = %@, k2 = %@", k, k2);
}
@end
Note that large JavaScript objects i.e. window
or document
, very expensive to convert to corresponding Objective-C, so the second way is preferred. Alternatively, you can use a parameter JSValue
to call JavaScript methods of this object from Objective-C using callWithArguments:
.
source to share