-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use StaticWebAssets v2 w/ MauiAssets #1905
Use StaticWebAssets v2 w/ MauiAssets #1905
Conversation
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
If I change the SDK of the "head" projects from the Razor SDK to just NetSDK, the static web asset error goes away, build succeeds, but the project still has no static assets. E.g. this file: https://github.com/dotnet/maui/blob/main/src/Controls/samples/Controls.Sample.MacCatalyst/Maui.Controls.Sample.MacCatalyst-net6.csproj#L1 They really shouldn't need to be Razor SDK to begin with. |
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking pretty good. Just got a few Qs on future-proofing things.
using var stream = _assets.Open(_filePath); | ||
using var memoryStream = new MemoryStream(); | ||
stream.CopyTo(memoryStream); | ||
return memoryStream.Length; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a note this is quite heavy, especially if this is a large file. Since it probably will never be called, it is not essential. However, this might be worth reading via a buffer of say 4K and then just keep reading into that.
var buffer = ArrayPool<byte>.Shared.Rent(4096);
long length = 0;
while (length != (length += source.Read(buffer))) {
// loop
}
ArrayPool<byte>.Shared.Return(buffer);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will update. I wish on Android there was a legit way to do this. You can't access the file system, calling AssetManager.OpenFd() isn't supported with compressed assets (which by default everything is), so you can get only a stream, and count the bytes as they flow by into nothingness :(
{ | ||
relativePath = _hostPageRelativePath; | ||
} | ||
relativePath = Path.Combine("Assets", _contentRootDir, relativePath.Replace("/", "\\")); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a note that this maybe should be a constant for now. I know there might be plans to make the images and assets go to other folders instead of just Assets. With Android, there is no choice, but since Windows might allow it, there is always someone that just has to use another folder.
Also, would this generally be configurable for all platforms because it may be the case that someone wants to put the web assets in Assets\wwwroot, and then have other, non-web stuff in Assets\Music?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
However, this is more for a later PR. Not sure about the desired configurability.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So ideally I would love there to be a runtime MauiAssets type that could do this for me. Was there ever any discussion on some kind of MauiAsset.GetItem(string path)
that would work on all platforms?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
cc @Redth for this too.
src/BlazorWebView/src/Maui/Windows/BlazorWebViewHandler.Windows.cs
Outdated
Show resolved
Hide resolved
One difference in the two items is the Is the app project searching through all dependencies? If this is a MauiAsset, it might be because we actually do that and check dependencies and collect them all. This is how we get a MauiImage to work when it is added to the shared project and not the head projects. How does the razor class library bundle the resources it needs for sharing? Is it embedded? |
/// <summary> | ||
/// A minimal implementation of an IFileProvider to be used by the BlazorWebView and WebViewManager types. | ||
/// </summary> | ||
internal sealed class iOSMauiAssetFileProvider : IFileProvider |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
internal sealed class iOSMauiAssetFileProvider : IFileProvider | |
internal sealed class IOSMauiAssetFileProvider : IFileProvider |
So it is similar to IOSWebViewManager
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@campersau this file is for serving static assets such as index.html, CSS, PNG, JS, etc. within the BlazorWebView. The WebViewManager calls into this file provider to get the contents of the files.
OK pushed a change from @javiercn that should fix the issue. The MSBuild targets that run are a bit different in single-project vs. multi-project. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great!
It was needed only for the embedded file provider, which is no longer used.
6d188db
to
e5702ee
Compare
@mattleibow said:
Nothing embedded. It's all done via a few... thousand... lines of MSBuild 😄 It runs targets in each project to gather the resources and it has custom manifest files that it uses to track what file came from where. Then with more MSBuild it processes those manifests to figure out what needs to be converted to a MauiAsset. |
This should be the final piece of the puzzle for preview 7: Getting Static Web Assets v2 to work with MauiAssets on all platforms.
This system enables using all the standard Blazor features available to Blazor devs to do with static assets, including scoped CSS, on all platforms. Static Web Assets (SWA) gathers all the metadata and the Blazor Desktop targets process that and convert it to MAUI assets. MAUI assets does platform-specific logic to get the assets delivered to the target device. Then at runtime Blazor Desktop has platform-specific logic to read the files back so that they can be served in the BlazorWebView control.
There is a breaking change for Blazor Desktop apps with .NET MAUI:
RegisterBlazorMauiWebView()
because it's not needed. Just callRegisterBlazorMauiWebView()
(no parameters).NOTE: Confirmed working on Android and WinUI; testing iOS/MacCatalyst right now.