A few years ago I created an app kodeWeave. Now kodeWeave uses a javascript library called JSZip which is used to create and download .zip files client-side.
However, I'm unable to download zip files using JSZip on my iPhone, but if the zip file is located on a server like Github I can actually download the zip file on my iPhone.
I thought at first it may just be the Chrome browser, however, I tested with other browsers such as Safari, Firefox, Edge, Dolphin Browser and MyMedia. All will open a new blob or blank tab but that's it, it just sits on a blank tab that does nothing.
Because I can download zip files on a server, this issue is specifically related to how JSZip is programmed. So my question comes in two parts.
1) Does anyone know how to solve this issue with JSZip?
and
2) Encase question 1 is not an option at all (at least until Apple improves their technology. Does anyone know of a way to dynamically save zip files to a server similar to how JSZip saves zip files through a blob?
The actual problem is not in JSZip but in FileSaver.js shown in example.
In FileSaver README there is a warning for iOS.
saveAs must be run within a user interaction event such as onTouchDown or onClick; setTimeout will prevent saveAs from triggering. Due to restrictions in iOS saveAs opens in a new window instead of downloading, if you want this fixed please tell Apple how this bug is affecting you.
Please also note other browsers support and their limitations for your application.
How to do that? I modified example from JSZip official website. As HTTP client I prefer axios, but you go with vanilla XMLHttpRequest or fetch.
var zip = new JSZip();
zip.file("Hello.txt", "Hello World\n");
var img = zip.folder("images");
img.file("smile.gif", imgData, {base64: true});
zip.generateAsync({type:"blob"})
.then(function(content) {
const file = new FormData();
file.append("blob", content)
axios.put('/upload/server', file, {})
.then(function (res) {
// done
console.info('Uploaded')
})
.catch(function (err) {
console.error('Failed due', err.message);
});
});