10
\$\begingroup\$

I am making an application using Phonegap where users can select and share files. When the user selects it, even if it goes offline or closes the app, I should upload it back to the server, so I need to store the reference file path.

Steps I have used:

  1. User selects/captures video or image using Camera.
  2. File may not contain extension to name in Android every time and in iOS when selected from Gallery.
  3. Get mimeType and then copy the file to myApp's folder with a new name and extension.
  4. Then again get mimeType and return.

Is it correct to copy a file to another location whenever the user selects a media file?

 var obj = {
    destinationType: navigator.camera.DestinationType[fromCamera ? 'FILE_URI' : 'NATIVE_URI'],
    // If I use NATIVE_URI for when taking from Camera it returns null.
    sourceType: navigator.camera.PictureSourceType[fromCamera ? 'CAMERA' : 'PHOTOLIBRARY'],
    mediaType: navigator.camera.MediaType[image ? 'PICTURE' : 'VIDEO']
}, that = this;

if (image && fromCamera) {
    obj.correctOrientation = true;
    obj.quality = 40;
}

return new Promise(function (resolve, reject) {
    navigator.camera.getPicture(function (url) {
        var fail = function () {
            resolve(false);
        }
        window.setTimeout(function () {
            // mimeType uses window.resolveLocalFileSystemURL to get fileEntry
            that.mimeType(url).then(function (mimeObj) {
                /* 
                    mimeObj contains object like below  
                    {lastModified:'', fileType:'', fileExtension:'', name : ''}
                */
                if (mimeObj) {
                    // that.fileSystem() resolves fileSystem
                    that.fileSystem().then(function (fs) {
                        // dirName is where I want to store all myApp's media files.
                        var dirName = 'myApp/media/' + (image ? "images" : "videos") + '/';
                        that.getFile(url).then(function (fileEntry) {
                            // getFile uses window.resolveLocalFileSystemURL and returns fileEntry
                            that.moveTo(fs, fileEntry, dirName, mimeObj.name).then(function (entry) {
                                // MoveTo fill copy the same file to directory where I am manintaing files.
                                mimeObj.localURL = entry.nativeURL;
                                /* 
                                    mimeObj is failing to find extension 
                                    when user selects it from different albums. But not when user uses Camera. 
                                    So I am making again mimeType call.
                                */
                                that.mimeType(mimeObj.localURL).then(function (mimeObj) {
                                    // This gives me exact mimeObj that I need.
                                    resolve(mimeObj);
                                });
                            }, fail);
                        }, fail);
                    }, fail);
                } else {
                    resolve(false);
                }
            });
        }, 0);

    }, function (fail_message) {
        window.setTimeout(function () {
            reject(fail_message);
        }, 0);
    }, obj);
});
\$\endgroup\$
  • \$\begingroup\$ But my question is also, whether is it correct to copy file and another location whenever user selects a media file in term of privacy or performance etc ? If the user is aware that you're copying files I think it's correct. In term of performance I have no idea. \$\endgroup\$ – Marc-Andre Sep 24 '14 at 14:07
  • \$\begingroup\$ @Marc-Andre I mean to say, as it is duplicating files does not it occupy more memory? So in terms of memory I feel that it is not a good solution. \$\endgroup\$ – SoI Sep 24 '14 at 15:07
6
\$\begingroup\$

Interesting question,

it is of course not good to fill up memory with copies of pictures. Especially with this scandal in recent memory where deleted pictures haunt users.

It seems from reading your code that you take a copy of the file whether or not you have the extension and MIME type. At least only copy if you see no other way.

Furthermore, from the documentation ( and I could be wrong ), the FileEntry object has a method called file which creates a File Object which has a type property which is the mime type of the file. Could this solve your conundrum ? If that does not work, you should see if you can file a bug.

From a real code review perspective, this is my quick once over:

  • Respect for dealing with this immature API
  • JsHint has nothing on this, except for 1 missing semicolon
  • Have you considered using 'use strict' ?
  • The multi-line comments definitely stop the reading flow, but removing them would reduce the value of your commenting. I wonder if those multi-liners can be part a narrative on top of your function..
  • You are at the limit of having to break things up into helper functions, as per this arrow half:

                                });
                            }, fail);
                        }, fail);
                    }, fail);
                } else {
                    resolve(false);
                }
            });
        }, 0);
    
    }, function (fail_message) {
    
\$\endgroup\$
  • 1
    \$\begingroup\$ Thanks for your comments :). I am making copy of the file as the file does not have extension, fileEntry.file also is unable to get me correct mime type and more importantly to keep the file safe in my hands (as iOS deletes temporary memory once I quit the app file reference does not work any more) I am copying it to my app's media folder. \$\endgroup\$ – SoI Sep 27 '14 at 20:56
  • \$\begingroup\$ Make the world a better place, file a bug report ;) \$\endgroup\$ – konijn Sep 29 '14 at 1:18
  • \$\begingroup\$ Oops, Now even files stored in Media folder got erased once I quit the app . I am gonna file bug. Thanks \$\endgroup\$ – SoI Sep 29 '14 at 19:41
  • \$\begingroup\$ @Sol, please also check this out: issues.apache.org/jira/browse/CB-6116 \$\endgroup\$ – konijn Sep 30 '14 at 19:36
  • \$\begingroup\$ Thanks for the link, for me resolveLocalFileSystemURL works fine with my current file plugin(may be because I am using latest). And what also I have learned is I should store my content in dataDirectory in iOS and externalDirectory in Android to be safe from iCloud in iOS and not to sync with Gallery in Android. \$\endgroup\$ – SoI Sep 30 '14 at 19:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.