Closed consp1racy closed 5 years ago
Thanks for the detailed proposal. Sure, this is something that would be quite useful. I have never been completely happy with the implementation of toJavaObject()
, but it worked for my limited purposes. As it happens, I have a nearly working version of LiquidCore for iOS. It is running Node.js on top of JavaScriptCore (rather than V8), and JSC object conversion to Objective-C and Swift already works as you describe. So it would be nice to have symmetry between the platforms.
One thing, though, if you haven't already managed this. You will probably need to add a test for handling circular values:
var a = {};
var b = { a : a };
a.b = b;
Passing either a
or b
to Java should not result in an endless loop.
Oh right, that's a good point. How did you solve it on the iOS side?
I seem to recall there's a list of all known JSObjects somewhere. So then I'd need to maintain a Map<JSValue, Object> of resolved JS valeus during the top-most toJavaObject
call.
I didn't solve it. It comes out of the box with JavaScriptCore. I'm not sure what it does with circular references. I will have to devise a test.
However, this did come up when I was building out the micro service implementation. JSON.stringify()
is not safe from circularity. See MicroService.java:279
.
Awesome, so for toJavaObject(String.class)
I should be able to leverage safeStringify
. For Object.class
I'll have to figure something out.
Also, another good catch, support for JSONArray and JSONObject as Java function parameter types.
According to this stringify throws an error if it encounters a circular reference.
Personally I'm okay with that happening in the Java bridge. At least in the toJavaObject(String.class)
method.
toJavaObject(Object.class)
could ~be bent to either support circular references or~ throw as well.
How much do you insist on safeStringify? For me it makes little sense to support circular references in any form across the bridge.
Closing due to lack of activity and demand.
There are three points to this.
Object.class
JSValue.tojavaObject(Object.class)
should return whatever that object would be in Java instead ofthis
(of typeJSValue
).This would allow pure Java bridge in the sense I'll try to describe here.
Sample
I'll be trying to pass the following object as a function argument from JS to Java:
The Java function defines parameter of type
Map<String, Object>
.Current behavior
Currently the resulting argument received by Java function could be described as
Map<String, JSValue>
, because everything coming from JS is aJSValue
. Only the top-most element is resolved asMap<String, Object>
.What I get (ordering is not guaranteed, that's fine for now):
Expected behavior
What I want is to completely abstract JavaScript from the Java function, unless the parameter is defined as
JSValue
or its children.Wanted result:
The same result would even be passed if the function parameter type was
Object
.String.class
Second case would be conversion to
String
. If Java function expects a string best effort should be made to convert whatever comes from JS to string. That meanstoString()
toNumber()
Detached results
Resulting objects should be detached from any original real JS objects. E.g.
HashMap
constructor resolves the dynamic map to actual stable values before passing that to the Java function.Future enhancements
Ability to plug in Moshi so it resolves
Map<String, Object>
or JSON string to arbitrary Java object types automatically.Motivation
I'm trying to replicate and expand the same API that WebView offers for registering JS to Java bridge using
addJavascriptInterface
. I want to hide anyJS*
objects from consumer. That also means a function handler should not need to extendJSObject
orJSFunction
.I'm working on this and will file a separate issue/pull request.
(This part is now over my head so I'm using ByteBuddy to generate child classes of
JSObject
at runtime that delegate method calls to whatever class the consumer supplied.Now what
I already have a working demo of the ideas described here (minus automated tests). Is any of this something that goes along with the goals of your library and you'd like to see merged?