unoplatform / uno

Build Mobile, Desktop and WebAssembly apps with C# and XAML. Today. Open source and professionally supported.
https://platform.uno
Apache License 2.0
8.77k stars 706 forks source link

[WASM] `FilePicker` can't Save files #13892

Open BertrandDeSaintBezier opened 11 months ago

BertrandDeSaintBezier commented 11 months ago

Current behavior

Currently, when trying to save bytes/a file to disk using FilePicker from the Wasm platform, the outputted file is empty. The file appears in the File Explorer, and can be interacted with even once closing the browser, but contains no data and cannot be opened.

image How the image appears in File Explorer. The same image was saved using the same functionality, once on WinUI and once on Wasm

image Wasm appears unable to write to disk, as the file size is 0 KB.

Expected behavior

When saving a file using FilePicker on Wasm, the output file should contain the relevant data, or at least not be empty - in essence, mirroring the existing behaviour on WinUI.

How to reproduce it (as minimally and precisely as possible)

Repro Project

Download the WasmFilePicker_Repro project. The project includes a Windows head and a Wasm head. The Windows head represents the functional part of the application, while the Wasm head is the one causing issues.

Additional Info

The project contains code that generates a QR Code, which can then be saved to disk. The QR Code generation and saving methods can be found in the QrCodeVisualizer class under the UserControls directory. The UserControl includes dependency properties to edit the image's data, should that be interesting.

The project makes use of the SkiaSharp packages for QR Code generation, as the System.Drawing namespaces and methods aren't available on other platforms.

To reproduce the expected behaviour :

To reproduce current behaviour :

Workaround

In this specific case, the FileIO.WriteBytesAsync(file, skData.ToArray()) can be used to save an SkImage from Wasm. The other FileIO.Write methods all seem to be working, with the exception of FileIO.WriteBuffer. In the author's tests, methods that relied on streams and buffers didn't seem to work at all on Wasm.

Works on UWP/WinUI

Yes

Environment

Uno.WinUI / Uno.WinUI.WebAssembly / Uno.WinUI.Skia

NuGet package version(s)

General SkiaSharp --> Version 2.88.6 Uno.WinUI --> Version 4.10.26

Wasm Head Uno.WinUI.Runtime.WebAssembly --> Version 4.9.26 SkiaSharp.Views.Uno.WinUI --> Version 2.88.6

Windows Head SkiaSharp.Views.WinUI --> Version 2.88.6

Affected platforms

WebAssembly

IDE

Visual Studio 2022

IDE version

17.7.4

Relevant plugins

SkiaSharp --> Version 2.88.6 Net.Codecrete.QrCodeGenerator --> Version 2.0.3

Anything else we need to know?

No response

jeromelaban commented 11 months ago

Thanks for the report. To be sure, have you followed this sample: https://platform.uno/docs/articles/features/windows-storage-pickers.html#filesavepicker ?

Windows.Storage.Pickers
BertrandDeSaintBezier commented 11 months ago

I hadn't tried using the FileIO.WriteTextAsync() method. I can confirm that the example given in the documentation works fine for saving text files, but other file methods like the FileStream, FileIO.WriteBuffer and File.OpenWrite used in the repro project don't work.

BertrandDeSaintBezier commented 11 months ago

In fact scratch that last comment, I was actually able to save a SkiaSharp image using the FileIO.WriteBytesAsync method. I'll include this as a workaround in the original post.

It seems like methods that don't involve Buffers and FileStreams work completely fine.