How to create and use bundle files with electron? - bundle

I am working on an electron app, where I want to load and modify a project folder. The project folder should only be modified by the app and easily exchangeable.
A folder is a great source of errors since everyone can enter it and modify the files. I would love to have some kind of protection for it. The best way I can think of is a bundle file. Something like the .app bundles from macOS or the .embersnap files from Realmac’s Ember app, which behaves as if it were a single file, but contains multiple resources.
Is there a way to use such bundle files with Electron? (Cross platform would be ace)

You can use the build in electron archiver asar.
var asar = require('asar');
var src = 'some/path/';
var dest = 'name.asar';
asar.createPackage(src, dest, function() {
console.log('asar archive created.');
})
The cool thing about asar is that you can access the files like they are unpacked. For example via the path ./name.asar/some/path/ just make sure to use nodes fs for accessing the file.

Related

I cant load HTML file into WebView from app specific storage since Android 11 (SDK30)

My App has the following use case:
We download a geojson file, a html file and some audio files from a server for a specific language a user has chosen and we are saving this in the app specific file directory.
The directory path is the following for each use case:
For the HTML file we have:
/storage/emulated/0/Android/data/my.example.com/files/ExampleApp/EnginePayload/de/html-file.html
For the json file we have:
/storage/emulated/0/Android/data/my.example.com/files/ExampleApp/LocationPayload/de/geojson-file.geojson
Audiodata:
/storage/emulated/0/Android/data/my.example.com/files/ExampleApp/Audio/de/intro.mp3
/storage/emulated/0/Android/data/my.example.com/files/ExampleApp/Audio/de/outro.mp3
and so on...
Since i have to change the minSDK and compileSDK to 30 i don't get the files to work.
I load the html-file.getAbsolutePath() to the webView but the webview client does not call ANY callback!
The audio files will not be started, because we use javascript functions to do that.
As i unterstand it, the app specific directory does not have to be changed because even on Android 11, the app has permission to read and write its own created files.
The moment i change it back to SDK 29, everything is working.
I don't know what to do. Can someone help me please?
I fixed it myself after hours!
My assumptions were right. The app had access to the files, because the app created them itself. so there was not an issue here to read the files...
Here is my fix and i hope it will help someone in the future:
There was something missing in the settings for the WebView.
webView.getSettings().setAllowFileAccess(true);
This allows me now to load a html file (with absolute Path) from the app specific directory for Android 11.
Here is my code:
webView.getSettings().setAllowFileAccess(true);
File extDir = cxt.getExternalFilesDir(null);
//htmlPath is something like this: "ExampleApp/EnginePayload/de/html-file.html"
File twine = new File(extDir.toString() + "/" + htmlPath);
webView.loadUrl(twine.getAbsolutePath());

How to distribute Image folder?

I have a sandboxed osx app which contains a huge number of logos as png-files.
If there are any logos missing, the app downloads the missing logos automitcally from the web.
Because the app is sandboxed, all logos are stored in a folder in Library > Applikation Support.
My question is now, how I could distribute the already existing logos with an app bundle?
The best way would be, if the app launches the first time, the logo-folder inside Application Support gets created and all Logos are copied from the bundle inside the new folder.
Is this possible with an app bundle or do I have to create an installer?
Any help would be much appreciated.
Let's see if we can round out the comments you've received so far.
My question is now, how I could distribute the already existing logos with an app bundle?
Short answer: just include them in the bundle as resources. Many applications include images for use in their GUI the only difference you have is maybe its a "huge number".
Long answer:
Here is the outline one way to do it:
Create a Group in Xcode, say Logos, which is associated with a folder (in Xcode 9 New Group generates the folder, prior to that you can create the folder-less Group and then use the File Inspector to add one).
Add your logos to this group. Do not mark these images as part of your target (otherwise Xcode will copy and flatten your folder structure)
Add a Copy Files or Run Script Build Phase to copy the images to a subfolder of Resources, say Logos.
As the images are part of your app bundle you can access them directly from there using standard bundle and file routines. There is no need to copy them anywhere.
Finally you managed to cause some confusion with the statement:
Because the app is sandboxed, all logos are stored in a folder in Library > Applikation Support.
It is unclear which folder you mean here, there are three obvious candidates:
System: /Library/Application Support
User: ~/Library/Application Support
Sandboxed App: ~/Library/Containers/<bundle id>/Data/Library/Application Support
If you are using the APIs (URLsForDirectory:inDomains:, URLForDirectory:inDomain:appropriateForURL:create:error:, NSSearchPathForDirectoriesInDomains), request the user domain, and are in a sandboxed app then (3) is returned instead of (2) and your sandboxed app has access to it with asking permission from the user.
A subfolder of Application Support (whichever one you use but (3) is recommended), typically named according to the bundle ID of your app, is the place you should store logos your app downloads – there is no need to copy images you include in your app bundle into the same location.
HTH

Cocoa Mac OS X application bundling 1000 images

We have a Cocoa Mac OS X application in which we want to bundle around 500 images. Each image is around 10kb so size isn't a problem.
These images are not exactly resources in the app, they are sample images.
Basically, we have simple button that would let the user copy these images to a directory.
The solution also needs to be "dump in, dump out" -- so we don't want to store individual image file names somewhere in our application; we just want to have a directory of images that can be copied.
How do I package these into my application?
The question turns into: How do I make a directory resource containing the images.
In our case everything gets flattened into the MyApp.app/Contents/Resources and this approach would require us to put image names in the app so that we can copy those.
Put the images into a folder. Drag the folder into your project in Xcode. In the resulting dialog, make sure you copy, make sure you create a folder reference, and make sure you add to your app target. Done. Now the folder is part of your app bundle and you can refer to it from your code without knowing anything about its contents.
The folder /Library/Application Support is for support files that, if deleted, would not affect the execution of an application. I would suggest this is ideal for your product's sample images.
As Apple's documentation states for Application Support:
Use this directory to store all app data files except those associated with the user’s documents. For example, you might use this directory to store app-created data files, configuration files, templates, or other fixed or modifiable resources that are managed by the app. An app might use this directory to store a modifiable copy of resources contained initially in the app’s bundle.
So, use pkgbuild / productbuild to install them to /Library/Application Support/<ProductName>/
Because size is not an issue, you can just put all your sample images in separate Asset Catalog file.

Bundling directory of images in app

Wondered if someone could help please:)
Titanium 5.5.0 sdk
Appcelerator 4.7.1
I need to be able to bundle a bunch of images in my iOS app and then get a directoryListing so the user can pick an image out of it.
In an older app I did this by placing my image directory in:
assets/iphone/[folder here]
and used this code:
var path = Ti.Filesystem.resourcesDirectory + '[nameoffolderhere]';
var imgDirectory = Ti.Filesystem.getFile(path);
var imagesArray = imgDirectory.getDirectoryListing();
and it worked. For some reason when I'm building a NEW app this no longer works. Indeed even the older app running under the latest SDK still finds the images. BUT using the exact same folder structure in a new app and it can't find the directory.
Could someone throw a light on the best place to place these directories so I can receive a directory listing and get to the images please?
thanks very much in advance
ade
Do you have <use-app-thinning>true</use-app-thinning> enabled in your tiapp.xml? If so, images are bundles with the asset-catalog are not accessible as files.
You should probably try to place them in app/platform/ios then, to copy them as resources instead of assets or disable app-thinning if you don't explicitly need it.

Reading JPG into BitmapData in ActionScript 3 (JPG is inside APK file)

I'm using Adobe AIR to make APK file for my Android phone. Inside the APK package there is a SWF file and in the same folder as the SWF file there is a subfolder named "images", which contains image.jpg.
I'm trying to read that image.jpg into the program at runtime but can't get the location of it (the program doesn't seem to find it.
Here's what I'm trying:
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onComplete);
loader.load(new URLRequest("images/image.jpg"));
while (bitmapData==null) {} //wait until loaded
return bitmapData;
The onComplete-function puts sets the bitmapData field. However, the COMPLETE event never happens so the while loop never exists.
I have also tried:
loader.load(new URLRequest("/images/image.jpg"));
loader.load(new URLRequest("app:/images/image.jpg"));
loader.load(new URLRequest("app-storage:/images/image.jpg"));
loader.load(new URLRequest("file:/images/image.jpg"));
None of it works.
I can't get this to work even when trying without the APK file, when only running the SWF file that is generated (the images subfolder is in the same folder as the SWF file).
I can't embed the JPG into the SWF file itself because I need to have a lot of image files and Flash CS6 runs out of memory when making such a big SWF file (reading the images externally would also mean a whole lot less compilation time).
Any ideas? How can I get put the external JPG file into BitmapData? Remember that the image is not outside of the APK file, it is packaged inside it.
Note: I'll also export the thing into a iOS ipa package later so it have to work there as well.
Edit because I can't self-answer due to my reputation.
Strille made me realize that the ActionScript Virtual Machine is single-threaded.
So it's impossible to make a thread sleep (wait) for an image being loaded. Instead I have to sigh rewrite a lot of code so that things are halted and continues when the onComplete function is called.
This thing that I tried before actually works but couldn't complete due to the while loop:
loader.load(new URLRequest("app:/images/image.jpg"));
If I remember correctly, you should be able to do it like this:
loader.load(new URLRequest(new File("app:/images/image.jpg").url));
Since we're using the File class, the above will not run in the Flash Player, just on iOS or Android.
From my experience there are two practical methods to load assets from a running Android APP using AIR
using URLLoader and .url property of the File instance
using FileStream (which receives a File instance)
Adding to project
You can package the files inside the APK using
the same technique as packaging ICONS, inside the .xml descriptor file for your app.
And make sure you add those to your IDE in the Android section (applies to IntelliJ and Flash Builder) "Files and folders to package"
- add the path to your wanted assets folder, and give it a relative name alias.
Elaboration
The assets themselves are placed (when the APP is installed),
inside the ''applicationDirectory'' which is available for AIR,
Yet since newer Android OS's, and Flash player security issues,
it is not possible to access those assets via the nativePath,
only the 'url' property of the File instance.
Best Practice
Use URLLoader and .url property of the File instance,
as it is also Asynchronous by nature and can resolve PNG / JPG files
using native decoder instead of having to do this manually
reading a FileStream (which returns a a ByteArray)
var f:File = File.applicationDirectory.resolvePath('images/myimage.png');
loader.load(new URLRequest(f.url));
and,
If I'm missing more ways, please let know... )

Resources