how to bundle flutter desktop assets into a single file for production build - flutter

after building the flutter project for desktop, flutter copies all asset files inside the assets directory into the build/flutter_assets/assets which are easily accessible and modifiable (which is not secure at all!), user can change the whole images easily and do some kind of modding the app with no experience required! or even in the worst situation with modifying the AssetManifest he could change the runtime dynamic libs with the malicious libs and get a hook from the app.
most modern frameworks/languages have the option to embed the resources inside a single file (that makes it harder to modify the files / repack the resource file) for example C#(WPF/Win32) embeds the resources in the resource Resource section or even Electron (Javascript) embed the whole resources into a file (it's easy but better than nothing)
I didn't find any similar behavior in Flutter Desktop (Windows/Mac/Linux) is there any alternative for flutter?

For now [12/12/22] it seems flutter desktop won't use resources to bundle the resources into a single file.
So I've created two separate libraries to achieve this
https://github.com/kooroshh/bundler that compresses the whole given assets into a single file and encrypts it with AES-128
https://github.com/kooroshh/flutter_bundler that reads the bundle file from and decrypts it into the memory that can be used with Image.memory or Direct file access using Virtual Files.
I hope an official solution gets implemented in the flutter framework.

Related

Is there any way to split data files into smaller chunks in Unity WebGL builds?

I am limited to the size of web applications I can build by the "Build\application.data" file.
I.e if its over a certain size I cannot upload it certain hosts, github, etc.
Ideally I would like to split the application into multiple data files under a certain size, while the application is still executable.
How would this be possible? Is this something I can do from Unity build configuration?
Can I do it after the build is done?
Can I split the file into chunks by archiving it with zero compression, and somehow still execute it from the browser? There is a file called Build.Loader.js, is it something that can be edited for this purpose?
This is for the purposes of using the application after it has been uploaded, not sharing it, I do not want to compress it into separate archives, or use gitlfs, I've tested this and the application does not work from the browser with github and gitlfs.
Thanks
Unity has 2 technologies for split data file:
Asset bundle
An AssetBundle is an archive file that contains platform-specific
non-code Assets (such as Models, Textures, Prefabs, Audio clips, and
even entire Scenes) that Unity can load at run time
Addressbles
The Addressable Asset System allows the developer to ask for an asset
via its address. Once an asset (e.g. a prefab) is marked
"addressable", it generates an address which can be called from
anywhere. Wherever the asset resides (local or remote), the system
will locate it and its dependencies, then return it.
Both technologies create separate files that you can host on a server and download as needed. Addressable is a newer technology that Unity team recommends.
Probably the total size of the bundle will grow, but user will be able to download only the necessary assets and the amount of data for the user may decrease
If you do not use Unity solutions, you can divide data file into parts. But on the client side (javascript) you will need to download all the parts, connect them and pass to Unity loader. You probably won't be able to use the browser's built-in gzip or brotli (not sure). It seems to be quite difficult.

When to use assets in Flutter

What is the best way to use assets in Flutter , for example if i have a file for app configuration , should I store the file by getting the app directory using the path_provider plugin -without using assets- and store it ?, or should I add the file to my program folder -add the file to my assets- ?
the same question if I have a small Sqlite database.
and which of these methods is faster , and which is more secure ?
Assets are files that you add to your app during development. You can load them with rootBundle.load() or rootBundle.loadString() but you cannot modify or delete them.
In the app's directory you can store any files that your app downloads or generates from the internet while running. These files can then be opened, deleted, modified, etc. To access your app directory you need the package path_provider, which tells you the path to your app folder.
A sqlite database is normally stored in the app directory. An example package would be here sqflite.
For speed and security I can't make a difference. An app directory is designed so that only the app can access it. Assets are a part of the app, the application file can theoretically be unpacked by anyone. Therefore I would at least not store secret things in the assets.
Well, if by app configuration you mean the user's settings you can use Sqlite, SharedPreferences or Hive (Hive shows a benchmark that says that it is faster than SharedPreferences).
I believe that assets folder is used to store some common files for the app, like images, icons, fonts, etc. And I think that isn't recommended to store files with some kind of config file, mainly with critical info about the app configuration.

Unity Asset Bundles - Which Files Do I Deploy?

I have created some asset bundles from my Unity assets using the directions given in the Unity documentation section on AssetBundle Workflow. After running the "Build AssetBundles" command, each asset bundle results in four files: myasset, myasset.meta, myasset.manifest, myasset.manifest.meta.
Now I am ready to deploy these bundles to a web server and implement downloading/caching in my Unity project. I have found numerous examples such as this that show the download URL to be a single file with a .unity3d extension. This is leading me to conclude that I am missing a step - I assume that all four of my files will be required by the app and that I have to do something to combine them into a .unity3d file first.
What file(s) do I need to deploy? Are there any additional steps that I need to take before my file(s) are ready to upload? Thanks in advance for any advice!
Just myasset will suffice.
Sometimes people optionally add .unity3d as a filename extension to their Asset Bundles. It is just a community convention, and is completely optional. Source (copied below)
Vincent-Zhang
Unity Technologies
Just a reminder, we don't have an official file extension ".unity3d" for asset bundle, it's not mandatory. You can use whatever file extension as you want, or without file extension.
But usually people use ".unity3d" as the file extension just because we used it in the official sample code at first time...
Unity creates the .meta files for all assets- you don't have to worry about those. In short, your myasset file is enough. I do not add file extensions to mine. Do note that if you use the strategy shown in the example that you shared that the client will re-download the bundle from the server every time. You need to additionally provide a version number if you want to take advantage of caching. You can see this in some of the method overloads here, the ones that have a Hash128 or uint "version" parameter. Caching is great because you can use the bundle that is already saved on the device next time instead of downloading from the server when no changes have occurred. The version/hash number you provide essentially gets mapped to the file name. Whenever a matching version is found, the file on disk is used. Update the version number to something else when the content changes to force the client to download anew.
You may want to reference the .manifest file for the CRC value listed there. You may have noticed a crc parameter in the link I shared as well. This can be used to ensure data integrity during transmission of the bundle data. You can make sure the downloaded content's CRC matches that of the bundle when you created it.

Streaming assets folder VS Resources Folder in Unity?

I want to Know the difference between Streaming assets folder and resources folder in Unity3d?
Want to extend answer by holo559.
Streaming Assets are just copied as files and can thus be accessed as such. Useful for including files like sqlite databases or other files you want to be able to use StreamReader on. They do not work on some platforms such as WebGL due to the web not having filesystem support. Can also be interchanged during runtime.
Resources are embedded into your program and are therefore platform independent. Useful for having example text files for configurations such as json or yml files.
Streaming Assets :
Any files placed in StreamingAssets are copied as it is to a particular folder on a target machine. Any asset placed inside StreamingAssets can be used while the application is running.
Resources :
Resources class allows you to find and access Objects including assets. You can access assets using "Resources.Load" stored in Resources. All assets in the "Resources" folders will be included in a build. This resources folder comes handy when we have to access multiple assets, instead of using their path names we can use its reference.
There are a few more differences worth mentioning:
1- Unity will include the dependencies of an asset when you put it in a Resources folder, Streaming Assets won't.
2- Using Resource API you can both load an asset and deserialize it. using Streaming Assets you have to do all file operations manually.
3- Resource API allows you to Unload unused assets.
4- Unity will try to create a lookup tree when your game launches, depending on the number of assets, this can take time.

How to write portable image paths in CSS files for a mounted sinatra app?

Background
You are writing a sinatra (or rack) application, and want to be able to use it, with no code changes, both as a standalone app, or as a mounted app.
That is, you might run this application on its own, or you might mount it as a sub-application inside some other app, by doing the following in your "config.ru":
run Rack::URLMap.new("/" => MainApp.new,
"/my_mounted_app" => MountedApp.new)
Everything seems to be going well, since you are careful to use sinatra's url() helper in all your views, ensuring that the correct paths will be generated regardless of how or if your app is mounted.
The problem
But now you want to include an image as a background in a CSS file, and you run into a dilemma:
Use the url() helper method inside your CSS file. This ensures your image paths are correct and portable, but now your CSS file has to be processed by sinatra on every request.
Use a build process, perhaps involving SASS and some global config file which has the path your app is mounted to, to generate your CSS files with the correct image paths. This also ensures correct paths, but introduces the complexity of a build process.
Is there a third, better option? Is the real problem mounting an app using URLMap -- is there another way to achieve mounting which avoids these problems?
Again, the goals are:
A fully portable app, which can be mounted without any changes.
Static assets that don't need to be processed by sinatra.
No static asset build process.
You can just use a relative URL in your CSS.
Since both the CSS and the image will be under the public dir the relative path between them will be the same wherever the app as a whole is mounted.