Open jonmdev opened 1 week ago
We've found some similar issues:
If any of the above are duplicates, please consider closing this issue out and adding additional context in the original issue.
Note: You can give me feedback by 👍 or 👎 this comment.
Thanks for this detailed feedback! I'll let @Eilon comment and break this one up.
Description
I spent the full day yesterday struggling to implement the .NET 9 HybridWebView. I wrote two bug reports based on that here and here. But after some rest, I thought it best to try again to better clarify and enumerate all the problems. This may help people as well until the issues are fixed.
1) Javascript functions are forced to always return something
@Eilon you said "The methods can be invoked as async, have optional return values, and optional parameters." However this does not seem to be the case.
If you run my bug project here or make your own, you can play with the functions and set for example in C#:
with Javascript:
You will get uncaught exception
Message = "'u' is an invalid start of a value. Path: $ | LineNumber: 0 | BytePositionInLine: 0."
which is something I saw all day yesterday. This is obviously not meaningful. This is the error for "no return received from Javascript," at least with string. It seems unintentional as you said your intent was to make returning optional, which I agree it should be. The forced return causes weird design patterns as I explained in my other thread and you will see here also.If you need to add a new type for
InvokeJavaScriptAsync<HybridViewNoReturn>
even that would be okay although a bit silly looking perhaps. My feeling is no return should be set by making the second argument null and then simply not awaiting obviously or if awaiting with second argument null it just returns immediately. Or for no return, a single or three argument untyped non-async function likeInvokeJavaScript("setBackgroundRandomColor", new object[]{arg}, new[]{ argType});
2) Return from Javascript must be precisely formulated
The only consistent way I could get such functions to return was as follows:
To "solve" this I thus created wrappers for all my Javascript code like above to access from C# and had them return something generic like this
returnOk
. But this is also I am sure unintentional based on your quote above stating return should be optional.If you try
return "Okay"
this doesn't work, orreturn "['Okay']"
orreturn '["Okay"]'
which sayThe JSON value could not be converted to System.String
. I am not sure of the rules here but usingJSON.stringify
on all string returns seems to solve it. I don't know how to manually format a string in Javascript to make it return without usingstringify
. Is there a manually written Javascrript string format that is accepted?3) Setting the second argument to null fails with an uncaught exception.
This is even if you have no intention of returning anything (and thus the second argument is irrelevant).
You can try this as:
4) Setting the fourth argument to null (or omitting) fails silently
If you use a function that invokes parameters, but omit the fourth argument (so it defaults to null) but use the first three arguments, it fails silently - the function is not called to my knowledge at all and nothing alerts you of this.
For example if you run this from C# you will get no errors:
with Javascript:
I did not test further but I imagine similar problems then if the count of objects in parameters and parameter json types are not the same (ie. this should cause a warning but doubt it will - for each parameter need one JSON type that is not null.)
5) Permissions requests cannot be caught in Android
It is no longer possible to catch permissions requests from Android HybridWebView using the available prior method as per: https://github.com/dotnet/maui/issues/25784 This obviously needs a fix.
Unlike the rest of things I mention here I found no workaround to this so it is likely the biggest issue.
6) Key documentation is hidden in GitHub
The only documentation of the new methods are in this thread and this article which are missing a lot of instruction and obviously GitHub is not an easy place to search. The GitHub page I only found by clicking through @Eilon's issue reports. The official Microsoft page needs more work.
7) Documentation needs section on sending raw messages from Javascript to C
It would ideally need a section explaining that the method to send messages from Javascript to C# (has changed names now) is called by the fullest name of
window.HybridWebView.sendRawMessage
or justHybridWebView.sendRawMessage
. This is not explained in the documentation I see. I see there is one line implementing this with Ctrl+F in one line of demo code, but a proper section explaining it would be better.8) Json Type method needs more explanation
This method is now key to the system. It should be elaborated on what it means, what it is doing, and with more types and their Json Type equivalents. It should also be clarified that this method creates errors in Visual Studio as you type, because these things are generated on build, and those errors disappear after building. I would add to the demo code (with further explanation):
Those would be the common types needed. None of this is immediately apparent and the logic for the expected names of the types for the created
JsonSerializerContext
(or how to debug what they will be if any code will tell you) should be better explained, especially given these are only actually created after building.9) Possible new design pattern?
If there is an intended use case (which I just thought of after yesterday) that we can trigger our own Javascript functions while bypassing all these typing and checking and returning issues (though I still think they should be fixed), this could be explained as that you can run
hybridWebView.sendRawMessage("functionName")
and then running in Javascript to receive:I am not sure if this would be an intended design pattern but it just occurred to me. One could create their own "interop language" just through the raw messages back and forth. This could provide similar function to the original design again except without the nice automatic parameter handling. We would have to manually parse our parameters out of the raw messages based on our own logic.
Conclusion
I think that's everything. It should have been a very quick conversion but took an entire day because of all the above. Fixing this will save other people the same problems.
Overall, the new system does work well once you understand all the issues above. I believe this change was implemented to fix problems with the .NET 8 method not returning properly or consistently and maybe some things being stripped out on build. If so, it is not a bad way of working. If it is necessary, so be it. It requires more explicit typing and boilerplate.
I do think returning from Javascript should be optional still somehow. Uncaught exceptions must be fixed. Permissions issue must be fixed of course.
Worse case scenario, one can code their own logic to work around all of this system with raw messages back and forth as noted above, though it probably should not be necessary really since this method is good once the bugs and issues above are removed.
Version with bug
9.0.0 GA
Is this a regression from previous behavior?
Yes, this used to work in .NET MAUI
Last version that worked well
8.0.0-preview.1.7762
Affected platforms
iOS, Android, Windows