Using TypedArray as a parameter in a Cordova plugin

I've been working on a plugin specifically for Cordova 3.3.

Within my JavaScript code, I'm in the process of downloading a PDF file which is being stored as a uInt8Array.

download: function ( ) {
        var xhr = new XMLHttpRequest();
        xhr.open('GET', 'url/to/pdf', true);
        xhr.responseType = 'arraybuffer';
        xhr.setRequestHeader('Accept', 'application/pdf');

        xhr.onload = function(e) {
            var uInt8Array = new Uint8Array(this.response); 

            window.plugins.filedownloader.saveFile(
                uInt8Array,
                "Downloads",
                function ( response ) {
                    console.log("success");
                },
                function ( response ) {
                    console.log("failure");
                }
            );
        };

        xhr.send();
    },

I pass the uInt8Array to the save method of my Cordova plugin. The JavaScript portion of my plugin appears as follows:

var exec = require('cordova/exec');

function FileDownloader() {
};

FileDownloader.prototype = {
    login: function ( loginUrl, params, username, password, successCallback, failureCallback ) {
        exec( successCallback, failureCallback, "FileDownloader", "doLogin", [ loginUrl, params, username, password ] );
    },

    getHtmlPage: function ( url, successCallback, failureCallback ) {
        exec( successCallback, failureCallback, "FileDownloader", "getHtmlPage", [ url ] );
    },

    downloadAndSaveFile: function ( url, saveFolder, successCallback, failureCallback ) {
        exec( successCallback, failureCallback, "FileDownloader", "downloadAndSaveFile", [ url, saveFolder ] );
    },

    saveFile: function ( data, saveFolder, successCallback, failureCallback ) {
       exec( successCallback, failureCallback, "FileDownloader", "saveFile", [ data, saveFolder ] );  
    }
};

FileDownloader.install = function () {
    if (!window.plugins) {
        window.plugins = {}
    }

    window.plugins.filedownloader = new FileDownloader();
    return window.plugins.filedownloader;
};

cordova.addConstructor(FileDownloader.install);

The save method within the Java section is as such:

public PluginResult execute(JSONArray args) {
                PluginResult result = new PluginResult(PluginResult.Status.OK, "blub");
                log("saveFile");

               try{
                   JSONObject dataValues = args.getJSONObject(0);
                } catch (JSONException e) {
                    e.printStackTrace();
                }

                return result;
            }

Now, the issue arises where the typedArray transforms into a JSONObject when passing it over. The indices of the uInt8Array become strings and are no longer ordered. Additionally, a new key "byteBuffer" is present.

Is there a method to handle a typedArray as a JSONArray when transferred to the Java part of the plugin, or should I explore an alternative solution to address this challenge?

Answer №1

There's a more efficient solution available.

Thanks to Sencha Touch, I no longer have to manually create the xhr object. In fact, as mentioned in the original question, doing so could lead to memory issues on iOS, potentially causing the app to crash when dealing with larger files.

Ext.Ajax.request() includes an undocumented option called responseType, which allows for fetching data as an arraybuffer.

downloadFile: function ( record ) {
    var me = this;
    Ext.Ajax.request({
        url: record.get("url"),
        method: 'GET',
        success: function ( response ) {
            me.onFileDownloaded( response, record );
        },
        failure: function ( response ) {
        },
        scope: this,
        responseType: "arraybuffer",
        timeout: 300000
    });

The response from this request is returned as an arraybuffer, which can be utilized as demonstrated below:

window.plugins.filemanager.saveUint8ByteArrayToFile(
            "Download",
            record.get("title"),
            response.responseBytes,
            response.responseBytes.byteLength,
            function ( filePath ) {
                me.onFileSaved( filePath );
            },
            function ( message ) {
                me.onFileSaveError( message );
            }
        );

When handling the response.responseBytes, Android will convert it into a base64 encoded String, while iOS will process it as NSData.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Cordova and ajax were unable to locate the rest service

Have you ever encountered the issue where placing an application on a mobile device and attempting to download JSON results in a 404 error with jquery mobile (ajax), yet the same device accessing the JSON response in a browser like Chrome works fine? Is i ...

Is there a way to prevent pixels from being rendered outside of a designated rectangle in HTML5?

I'm looking to add screen-in-screen functionality to my HTML5 game, and I have an idea for how to approach it: //Function called every frame function draw(){ set a mask rectangle only draw pixels from the current frame that fall within this recta ...

What are the recommended methods for injecting db and logger into routes in an Express application?

When working with Express and needing to pass single instance references like a logger or database to routes, I have come across three options. The first option is to attach it to the request object through a middleware: app.use(function(req,res,next){ re ...

Capture an image from the webcam without any manual intervention and store it in the system's directories

Looking to automate the process of capturing a picture from a webcam once access is granted, and then saving it without any user intervention. I've managed to capture the image but struggling with: A) Automating the capture process B) Saving the ca ...

Adding ngrx action class to reducer registration

Looking to transition my ngrx actions from createAction to a class-based approach, but encountering an error in the declaration of the action within the associated reducer: export enum ActionTypes { LOAD_PRODUCTS_FROM_API = '[Products] Load Products ...

Arrange information by using a Pageable with specified ordering

I've been developing a spring boot project that involves retrieving records from a database using a get API with specific filters and pagination. To achieve this, I am utilizing JPA alongside JPA Specifications. The API is functioning properly with th ...

Using Xpath language with the presence of both single quotes (') and forward slashes (/) in the text

How can I properly write an XPath expression that includes both a single quote(') and a forward slash (/)? a[.="what's in/out"] ...

The error message "Uncaught TypeError: Unable to retrieve the 'length' property of an undefined object in Titanium" has occurred

Here is the data I am working with: {"todo":[{"todo":"Khaleeq Raza"},{"todo":"Ateeq Raza"}]} This is my current code snippet: var dataArray = []; var client = new XMLHttpRequest(); client.open("GET", "http://192.168.10.109/read_todo_list.php", true); c ...

Display the image title in a separate div when hovering over it

As a beginner in jQuery, I am working on creating a gallery that displays the title attribute of an image in a separate div when hovering over the image. The title should disappear when the mouse moves away from the image. I hope that explanation is clear! ...

Issue with Angular and Karma: HTTP GET request not running

Currently, I am working on an AngularJS project that utilizes Karma to execute some unit tests directly in the browser. To conduct these tests, I have opted for mocha as the test framework. The challenge I am facing lies in running specification tests tha ...

What is the best way to check if a Java String matches a series of numbers?

Users can input a wide range of characters such as "0", "1", "2", "F", "?", etc., which are then stored in a String variable. Is there a more efficient way to check if the value stored in the string falls within the range of 1 to 8, without using multiple ...

Unconventional way of assigning class properties in Typescript (Javascript): '?='

Recently, I came across the ?= assignment expression within a class property declaration. Can anyone provide some insight into what this means? I am familiar with the new Optional Chaining feature (object?.prop), but this particular syntax is unfamiliar t ...

"Encountered a problem when trying to access file with node

An error has occurred: module.js:471 throw err; ^ Error: Module not found at '/Users/vinclo/app.js' at Function.Module._resolveFilename (module.js:469:15) at Function.Module._load (module.js:417:25) at Module.runMain (module.js:604:10) at run ( ...

Detecting collisions in three.js – a comprehensive guide

Currently, I am working with three.js and have incorporated two mesh geometries into my scene. I am looking for a way to detect collisions if these geometries intersect or would intersect when translated. How can I carry out collision detection using thre ...

The CSS transition will only activate when coupled with a `setTimeout` function

After using JavaScript to adjust the opacity of an element from 0 to 1, I expected it to instantly disappear and then slowly fade back in. However, nothing seems to happen as anticipated. Interestingly, if I insert a setTimeout function before applying th ...

Error: Unable to access the 'prototype' property of an undefined object (inherits_browser.js)

After updating our app to a newer version of create-react-app, we started encountering the following error: https://i.sstatic.net/ILdsl.png This error seems to be related to inherits_browser.js, which is likely from an npm module that we are unable to id ...

The disappearance of the checkbox is not occurring when the text three is moved before the input tag

When I move text three before the input tag, the checkbox does not disappear when clicked for the third time. However, if I keep text three after the input tag, it works fine. Do you have any suggestions on how to fix this issue? I have included my code be ...

AngularJS is incapable of detaching forms from objects

Creating forms dynamically using ng-repeat and adding them to the vm.forms object is causing issues. When an item is removed from the array, the corresponding form is deleted but the key in the vm.forms object remains, leading to undefined errors. angul ...

Stop the promise chain when the first error callback is encountered

Here is a sequence of promises I am dealing with: Transaction.findPublic({}).then(function(transactions) { combined = combined.concat(transactions); return JoinEvent.find().exec(); }, function(err) { return res.status(503).send(er ...

Button for liking posts on Facebook made of titanium

I am attempting to publish a like for a page from my Titanium Alloy application. var fb = require('facebook'); fb.appid = "1234567890"; fb.permissions = ['public_profile', 'email', 'publish_actions']; fb.addEventLi ...