Closed Eilon closed 4 years ago
The code is now checked in!
Check out the two samples to learn more about how to use this feature:
Tagging @jspuij who has been working on https://github.com/jspuij/BlazorWebView and with whom we will be collaborating on this project.
@jspuij , I'm looking forward to working with you more on this project!
And tagging @SteveSandersonMS whose great work went into this!
If you want to try it out, please clone the repo & build locally. We will have a preview out soon!
Great to see hybrid apps with all C# logic and a single markup syntax!
I wonder if the idea of C# Markup could also apply to Blazor HTML? (and therefore this hybrid approach). That could even further simplify the mix - C# for markup and logic, both mobile and web.
So instead of adding a separate HTML-like markup syntax on top of C# like mobile blazor bindings does, go the other way: Add C# HTML markup helpers on top of Blazor. The object model for HTML will be different from the Forms one (same as with Blazor syntax for mobile and web), but devs will be able to use C# + .NET for markup and logic. That means less friction, less cognitive load, no language bridging tools/frameworks/patterns needed.
A bit radical, but so was creating markup in Forms in C# instead of XAML.
@VincentH-Net, although for F#, elmish already works on .net: https://elmish.github.io/elmish/ IF you want to go the F# way entirely, Bolero is very cool as well, and runs on top of Blazor, with MVU built in: https://fsbolero.io/
@Eilon By some reason I got the following error:
Also would be nice to add example for Android HibridMessageAppSample
Thanks @jspuij for pointing out https://fsbolero.io/. Basically I want something for C#, MVU and MVVM, similar to their F#:
So devs get to select and mix language, pattern and markup syntax any way they like, with maximum skill reuse. I already prototyped this for mobile C# markup in MAUI (top: MVU, bottom: MVVM):
I will be looking into Bolero to see how they create F# markup in Blazor webassembly, and try a similar approach in C#. That will give devs hot reload of C# Markup with https://www.livesharp.net/
@redradist - can you share the steps you took when you saw that error? I'm not surprised if there are some threading issues but any info you can provide will help get this fixed.
@VincentH-Net - I'm working with the .NET MAUI team to do our best to give everybody everything that they need to be productive. For this repo the focus is on using Blazor to author .NET MAUI apps, in addition to the other ways already being planned for .NET MAUI apps (C#-based and XAML-based). In addition to these, do you feel there is a gap that you'd like to see addressed?
@Eilon
@redradist - can you share the steps you took when you saw that error? I'm not surprised if there are some threading issues but any info you can provide will help get this fixed.
I did nothing special, just compiled and run on my Android device and saw such screen
@Eilon @redradist I will spend some time on this this weekend. Very busy week sorry.
@redradist I am able to reproduce this issue now in my Android emulator. It might be a simple fix to switch to the right thread. I will post here when I learn more.
@redradist it looks like it was an easy fix: https://github.com/xamarin/MobileBlazorBindings/commit/d835416246b1d2ac5079dd8ffdbeb4bf2dd1cc1e
If you pull the latest changes, hopefully you'll see it working on Android now!
@Eilon Now it works, thanks !!
But there are compilation errors for projects other than HybridAppSample
@Eilon
@redradist it looks like it was an easy fix: d835416
If you pull the latest changes, hopefully you'll see it working on Android now!
I also think that HybridApp
should reference to Blazor WebAssembly
project, because it is easier to integrate and maintain Web Client
and HybridApp
@redradist thank you for the feedback. There should be no need for Web Assembly because the app code already runs as 100% C# code! There is a tiny bit of JS code just to communicate between the WebView browser components and the rest of the app, but the user doesn't write any code that is run as WASM/JS. Please let me know if you have additional thoughts on this.
Also, I just added the Android version of HybridMessageApp! Check it out in this commit: https://github.com/xamarin/MobileBlazorBindings/commit/0effaabc2e915bd3280b955527ba51b6281d1896
Can you share which compilation errors you're seeing in the app? I sometimes do a git clean -xdf
or a Rebuild in VS to ensure that old content isn't messing things up. Unfortunately I also sometimes have problems getting things to compile and I have not been able to figure out what is causing it.
@Eilon
@redradist thank you for the feedback. There should be no need for Web Assembly because the app code already runs as 100% C# code! There is a tiny bit of JS code just to communicate between the WebView browser components and the rest of the app, but the user doesn't write any code that is run as WASM/JS. Please let me know if you have additional thoughts on this.
Also, I just added the Android version of HybridMessageApp! Check it out in this commit: 0effaab
Can you share which compilation errors you're seeing in the app? I sometimes do a
git clean -xdf
or a Rebuild in VS to ensure that old content isn't messing things up. Unfortunately I also sometimes have problems getting things to compile and I have not been able to figure out what is causing it.
@Eilon I mean the I do not want to copy my Blazor WebAssembly project in MobileBinings ... From my point of view would be good the following structure of the projects: BlazorWebAssembly HibridApp // Referenced to BlazorWebAssembly ASP.NET // For API for BlazorWebAssembly and HibridApp Android // Referenced to HibridApp iOS // Referenced to HibridApp
I do not want to copy part in Red Rectangle from Blazor WebAssembly to HybridApp
As for me it would be nice if Blazor WebAssembly would be shared between Web App and HybridApp
@Eilon Below I have attached screen with errors:
@redradist ah I see, you want to share the same components/pages you have in your Blazor Web App also in your Blazor Hybrid App? I've been talking to @jspuij about what would need to happen to make this work. It probably doesn't work well right now, but I think it's definitely something we want to have good support for!
As for the errors:
macOS
project, unless you're building on a Mac (which you aren't), right-click on the two macOS projects and select Unload
. This will prevent those errors from appearing.Android
projects, I will take a look at those. I've seen the first 2 errors (Weather app) before, and I thought I fixed it, but it keeps coming back ☹️ For the 2nd two errors (Todo app), I've never seen that before. Did you try cleaning the project and/or closing VS and doing a git clean -xdf
?I submitted a fix for the Android Weather app resource issue. Apparently the fix is to not check them in, thus avoiding it breaking all the time when other things change. The resource file will be auto-generated on each build.
But if you can let me know more about the last 2 Android resource issues in the Todo app and I will try to investigate.
@redradist ah I see, you want to share the same components/pages you have in your Blazor Web App also in your Blazor Hybrid App? I've been talking to @jspuij about what would need to happen to make this work. It probably doesn't work well right now, but I think it's definitely something we want to have good support for!
As for the errors:
- For the
macOS
project, unless you're building on a Mac (which you aren't), right-click on the two macOS projects and selectUnload
. This will prevent those errors from appearing.- For the
Android
projects, I will take a look at those. I've seen the first 2 errors (Weather app) before, and I thought I fixed it, but it keeps coming back frowning_face For the 2nd two errors (Todo app), I've never seen that before. Did you try cleaning the project and/or closing VS and doing agit clean -xdf
?
@Eilon I think if it is possible to share webassembly without coping in this repo https://github.com/Daddoon/BlazorMobile than it should be possible to do
One advantage of this is that WebView version could be developed independent of Mobile and Browser versions
It would be also nice to have ability to use API from razor pages (maybe it is possible already I have not checked) and also to know on which platform code is running (Browser or WebView like in repo above)
@redradist What @Eilon is referring to, is that the current version of the WebView in MobileBlazorBindings does not yet support Static Web Assets in Razor Class Libraries. However, you can probably get it to work now if you want by roughly following the first part of this tutorial: https://jspuij.github.io/BlazorWebView.Docs/pages/prepare.html
This will take the parts out of a WebAssembly project and move them to a shared RCL library. You will probably need the EmbeddedFileProvider that @Eilon uses to add the wwwroot folder to the shared assembly, for as long as Static Web Assets are not supported yet.
Full support for Static Web Assets will come, this is a very first preview.
Regarding support for razor pages: There is no webserver (just a handler that intercepts the Http Requests from the browser), there is no ASP.NET core, so I'm not sure how you'd see Razor Pages working together with Blazor in this instance. This is the fundamental difference between this solution and BlazorMobile: BlazorMobile runs a web server internally.
I'd advise against platform detection. If you're the end developer you can set a variable with the platform yourself depending on the entry point of the application (every platform has it's own main method) or a preprocessor constant. When you're a library developer you really should be doing feature detection instead of platform detection. E.g. webassembly does not support threading yet. You could try and detect the Mono runtime to determine that you're running webassembly, but this has two disadvantages:
So it's better to try and create a thread and catch the exception, or detect threading support some other way, instead of relying on the platform.
However if you do want to detect the platform there is: https://docs.microsoft.com/en-us/xamarin/essentials/device-information?tabs=ios
@jspuij
@redradist What @Eilon is referring to, is that the current version of the WebView in MobileBlazorBindings does not yet support Static Web Assets in Razor Class Libraries. However, you can probably get it to work now if you want by roughly following the first part of this tutorial: https://jspuij.github.io/BlazorWebView.Docs/pages/prepare.html
This will take the parts out of a WebAssembly project and move them to a shared RCL library. You will probably need the EmbeddedFileProvider that @Eilon uses to add the wwwroot folder to the shared assembly, for as long as Static Web Assets are not supported yet.
Full support for Static Web Assets will come, this is a very first preview.
The repo https://github.com/Daddoon/BlazorMobile already supports Static Files that was added to *.zip file according this tutorial https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/webview?tabs=windows
I hope you will add it, it'll simplify working with Web version and Mobile version
Regarding support for razor pages: There is no webserver (just a handler that intercepts the Http Requests from the browser), there is no ASP.NET core, so I'm not sure how you'd see Razor Pages working together with Blazor in this instance. This is the fundamental difference between this solution and BlazorMobile: BlazorMobile runs a web server internally.
By Razor Pages I mean Blazor Pages ;)
I'd advise against platform detection. If you're the end developer you can set a variable with the platform yourself depending on the entry point of the application (every platform has it's own main method) or a preprocessor constant. When you're a library developer you really should be doing feature detection instead of platform detection. E.g. webassembly does not support threading yet. You could try and detect the Mono runtime to determine that you're running webassembly, but this has two disadvantages:
* iOS, macOS and Android in a hybrrid app also use Mono. So this solution will incorrectly assume that it runs on webassembly for these platforms. * Some day WebAssembly will support threads, and then you will have to update your code because it assumed that threads are unavailable on a platform.
So it's better to try and create a thread and catch the exception, or detect threading support some other way, instead of relying on the platform.
However if you do want to detect the platform there is: https://docs.microsoft.com/en-us/xamarin/essentials/device-information?tabs=ios
I need platform detection to know what API I can call from Blazor Pages ( Mobile is available ?? ) At least I want to know if Mobile or Browser version
Take a look how it was done in https://github.com/Daddoon/BlazorMobile , it is pretty clear and straightforward, I can call from Blazor page Xamarin.Essential API or other (like Xamarin.Forms) that is available to me
I need platform detection to know what API I can call from Blazor Pages ( Mobile is available ?? ) At least I want to know if Mobile or Browser version
You really don't. You can set an App.Mobile static boolean on true from the mobile entry point, and don't set it from the webassembly entry point. But it would be better to create a class "SupportedFeatures", add a property "GeoLocation" to it, and set it to true or false depending on detection, or constant at the start of the application. Or you can do a little fancier and register different services for the same interface depending on the platform in the DI container.
Take a look how it was done in https://github.com/Daddoon/BlazorMobile , it is pretty clear and straightforward, I can call from Blazor page Xamarin.Essential API or other (like Xamarin.Forms) that is available to me.
Yes, and it calls the Xamarin platform detection internally:
and if it does not detect a mobile or desktop platform, it assumes webassembly or SSB:
However it's fundamentally the wrong approach. It seems simple at first, but you will tie the availability of a feature to a specific platform. Then when a platform gains the capability, you find yourself checking 100 pages where you have if statements or switch statements depending on the platform.
Using DI to inject different services on each platform is my default recommendation. There might be cases where it doesn't work, but I expect those to be relatively rare. You can learn about backend-specific services here: https://docs.microsoft.com/en-us/mobile-blazor-bindings/advanced/backend-specific-services and apply similar logic in your apps.
@VincentH-Net - I'm working with the .NET MAUI team to do our best to give everybody everything that they need to be productive. For this repo the focus is on using Blazor to author .NET MAUI apps, in addition to the other ways already being planned for .NET MAUI apps (C#-based and XAML-based). In addition to these, do you feel there is a gap that you'd like to see addressed?
Thanks @Eilon , my apologies for my late reaction - I first wanted to compare Mobile Blazor Bindings to C# Markup hands-on. I did that in this blog post C# Markup versus Mobile Blazor Bindings in .NET MAUI.
The comparison may be valuable for devs looking into either. This is what it looks like:
The gap I'd like to see addressed is create C# Markup for regular Blazor, so MAUI developers can also build web apps and hybrid apps with all C# markup. That is not a topic for this repo, I agree. Eager to see how this will all pan out
Ah, I think I see. So you want Blazor-style programming, but from C#, not markup? I think that's an interesting idea. I agree this isn't the repo for it because this is all about using existing Blazor for native and hybrid scenarios. I think creating an issue or discussion on https://github.com/dotnet/aspnetcore would be a great place to gather broader input on that idea.
And, I would add that, generally speaking, any feature that Blazor itself gets, would pretty much "just work" in Mobile Blazor Bindings. We don't really customize Blazor at all - we just plug into its existing build/compilation system and its component system. It's just that the components are native, not HTML (but Blazor doesn't care).
I'm closing this issue now that the main feature is code complete and checked in. There are also new templates, and we'll have new docs to go along with it. Stay tuned for the upcoming release!
And, I would add that, generally speaking, any feature that Blazor itself gets, would pretty much "just work" in Mobile Blazor Bindings. We don't really customize Blazor at all - we just plug into its existing build/compilation system and its component system. It's just that the components are native, not HTML (but Blazor doesn't care).
@Eilon Interesting. You must know your way around the Blazor architecture quite well. Would you be in for it if I contact you in a month or so, see if you can give me some pointers?
@VincentH-Net - all the work here is from sitting atop the shoulders of giants! I've learned a thing or two along the way, though. Feel free to contact me at elipton !at! microsoft.com.
Adding support for hybrid app scenarios will enable developers to use Blazor for the Web to build parts of their app. This will be done by using a platform-specific embedded WebView on supported platforms, which will host Blazor web components. This can be mixed with Mobile Blazor Bindings for native portions of the app to enable the Blazor syntax and app model everywhere in the application. This will also help demonstrate how truly awesome Blazor is 😁
We are looking to support these platforms:
And here's an idea of what you can do with it in a WPF app (the same exact app works on all platforms):
Here are some previous requests for such a feature that will be closed in favor of this tracking issue:
119: Hybrid webview support ?
114: [Question] Is it possible to use native Blazor syntax within Mobile Bindings ?
There will be some follow-up work after the initial change: