Hi ,We are facing an issue with PDF download on mobile devices.We have a Reactive Web Application (PWA) developed in OutSystems 11. When the same application is accessed from a desktop browser, PDF download works correctly. However, when accessed through the mobile app/PWA, the PDF is not getting downloaded.Could you please help investigate the issue? Also let us know if there are any known limitations or additional configurations required for PDF download in mobile browsers/PWA applications.Details:
Please suggest the required checks or a solution.
I faced a similar issue with PDF downloads in an OutSystems 11 Reactive Web Application (PWA). The PDF download worked correctly on desktop browsers but did not work on mobile devices.
I resolved this issue using the following approach.
### 1. Add the FileSaver.js script
First, include the following FileSaver.js library to handle file-saving functionality.
```javascript
var saveAs = saveAs || function(e) {
"use strict";
if (typeof e === "undefined" ||
typeof navigator !== "undefined" &&
/MSIE [1-9]\./.test(navigator.userAgent)) {
return;
}
var t = e.document,
n = function() {
return e.URL || e.webkitURL || e;
},
r = t.createElementNS(
"http://www.w3.org/1999/xhtml", "a"
),
o = "download" in r,
a = function(e) {
var t = new MouseEvent("click");
e.dispatchEvent(t);
i = /constructor/i.test(e.HTMLElement) || e.safari,
f = /CriOS\/[\d]+/.test(navigator.userAgent),
u = function(t) {
(e.setImmediate || e.setTimeout)(function() {
throw t;
}, 0);
s = "application/octet-stream",
d = 1e3 * 40,
c = function(e) {
var t = function() {
if (typeof e === "string") {
n().revokeObjectURL(e);
} else {
e.remove();
};
setTimeout(t, d);
l = function(e, t, n) {
t = [].concat(t);
var r = t.length;
while (r--) {
var o = e["on" + t[r]];
if (typeof o === "function") {
try {
o.call(e, n || e);
} catch (a) {
u(a);
p = function(e) {
if (/^\s*(?:text\/\S*|application\/xml|\S*\/\S*\+xml)\s*;.*charset\s*=\s*utf-8/i.test(e.type)) {
return new Blob([
String.fromCharCode(65279), e
], {
type: e.type
});
return e;
v = function(t, u, d) {
if (!d) {
t = p(t);
var v = this,
w = t.type,
m = w === s,
y,
h = function() {
l(v, "writestart progress write writeend".split(" "));
S = function() {
if ((f || m && i) && e.FileReader) {
var r = new FileReader();
r.onloadend = function() {
var t = f ? r.result :
r.result.replace(
/^data:[^;]*;/,
"data:attachment/file;"
);
var n = e.open(t, "_blank");
if (!n) {
e.location.href = t;
t = undefined;
v.readyState = v.DONE;
h();
r.readAsDataURL(t);
v.readyState = v.INIT;
if (!y) {
y = n().createObjectURL(t);
if (m) {
e.location.href = y;
var o = e.open(y, "_blank");
if (!o) {
c(y);
if (o) {
setTimeout(function() {
r.href = y;
r.download = u;
a(r);
S();
w = v.prototype,
m = function(e, t, n) {
return new v(e, t || e.name || "download", n);
if (typeof navigator !== "undefined" &&
navigator.msSaveOrOpenBlob) {
return function(e, t, n) {
t = t || e.name || "download";
e = p(e);
return navigator.msSaveOrOpenBlob(e, t);
w.abort = function() {};
w.readyState = w.INIT = 0;
w.WRITING = 1;
w.DONE = 2;
w.error = w.onwritestart = w.onprogress =
w.onwrite = w.onabort = w.onerror =
w.onwriteend = null;
return m;
}(typeof self !== "undefined" && self ||
typeof window !== "undefined" && window ||
this.content);
if (typeof module !== "undefined" && module.exports) {
module.exports.saveAs = saveAs;
} else if (typeof define !== "undefined" &&
define !== null && define.amd !== null) {
define("FileSaver.js", function() {
return saveAs;
```
### 2. Add the following JavaScript to download the file
After adding the FileSaver.js script, use the following JavaScript in the appropriate JavaScript element to convert the Base64 file content into a binary buffer and save the file.
function fixBinary(base64Str) {
var base64Array = base64Str.split(",");
var base64Raw = base64Array.length > 1
? base64Array[1]
: base64Array[0];
var bin = atob(base64Raw);
var length = bin.length;
var buf = new ArrayBuffer(length);
var arr = new Uint8Array(buf);
for (var i = 0; i < length; i++) {
arr[i] = bin.charCodeAt(i);
return buf;
var binary = fixBinary($parameters.FileContent);
var blob = new Blob([binary], {
type: $parameters.FileType
cordova.plugins.saveDialog.saveFile(
blob,
$parameters.FileName
).then(function() {
$parameters.Success = true;
$resolve();
}).catch(function(reason) {
$parameters.Success = false;
$parameters.ErrorMsg = reason;
### Important notes
- Ensure that the required Cordova file-saving plugin is installed and configured.
- The second script uses `cordova.plugins.saveDialog.saveFile()`, which requires a compatible Cordova environment; it will not work directly in a standard mobile browser or standalone PWA without that plugin.
- Make sure the input parameters `FileContent`, `FileType`, and `FileName` contain the correct values.
I hope this helps anyone facing a similar PDF download issue in OutSystems 11 Reactive Web Applications.
@Chandra Vikas Sharma : The logic used to download files in a web application may not work when the application is packaged as an IPA/APK. For native builds, one option you could try is using the Social Sharing plugin (https://www.outsystems.com/forge/component-overview/7270/easy-social-sharing-plugin-o11). At a high level the algorithm is
I have attached a sample implementation for your reference. Do not remove the reference to Social Sharing Plugin even though none of its methods are directly referenced else it will fail when you compile to ipa / apk. btw you can refer any of the Social Sharing Plugin as long as its referring https://github.com/EddyVerbruggen/SocialSharing-PhoneGap-Plugin