» Fig Leaf Software Home

We've Got You Covered.

Tuesday, June 24, 2014

Sencha Touch 2.3: Downloading and Saving Binary Files to Local Devices with PhoneGap/Cordova

Sencha Touch 2.3 has added a new Cordova/PhoneGap abstraction layer to the Ext.Device class. Unfortunately the documentation/guides don’t seem to have an example of downloading and saving a binary file to the device’s filesystem.
Since mobile connectivity can be unreliable and usually produces high latency, being able to cache large documents on the device is critical for developing high-performance apps.
Before you can get started, you’ll need to install phonegap:
  1. Install Java JRE
  2. Install Node.JS
  3. Install PhoneGap by typing the following at a command prompt:
    npm install -g phonegap
Next, you’ll need to use Sencha Command 4.x+ to create a phonegap project. Simply change directories to the root of your application’s folder and issue the following command:
sencha phonegap init [AppId]
Where [AppId] is your application’s id (e.g. com.figleaf.myapp)
This will create a /phonegap folder off your project root.
Change directories to the phonegap subdirectory and install common phonegap plugins to enable the Sencha Touch Ext.Device classes to detect device type, enable file system access, and get real-time network information:
  • phonegap plugin add org.apache.cordova.device
  • phonegap plugin add org.apache.cordova.file
  • phonegap plugin add org.apache.cordova.network-information
Now you can get started with adding the download feature!
Request access to the local filesystem by using the code below, which I typically place in the application’s launch function, caching the result in the application object.
1
2
3
4
5
6
7
8
9
10
11
Ext.device.FileSystem.requestFileSystem({
     
    type: PERSISTENT,
    size: 50 * 1024 * 1024, // 50mb -- gonna store video
    success: function(fs) {
        MyApp.app.Fs = fs;
    },
    failure: function() {
        Ext.Msg.alert("FileSystem Error","Could not access the local file system<br>You will not be able to save notifications for offline use.");
    }
});
The following controller function illustrates how to download a file with a progress indicator and save it locally on the device. Note that the local file URL is returned to the callback function and would typically be written to a data store.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
saveFile: function(url,recordId,prompt,callback) {
 var me = this;
 // create progress indicator
 var progIndicator = Ext.create('Ext.ProgressIndicator', {
    loadingText: prompt + " {percent}%",
    modal: true
 });
 // create unique filename
 var fileName = url.split('/');
 fileName = fileName[fileName.length - 1];
 fileName = "notification-" + recordId + '-' + fileName;
 // let's get the party started!
 Ext.Ajax.request({
    url: url,
    timeout: 180000,
    useDefaultXhrHeader: false,
    method: 'GET',
    xhr2: true,
    progress: progIndicator,
    responseType: "arraybuffer",
    success: function(response) {
        
       var blob = new Blob([response.responseBytes],
                            {type: response.getResponseHeader("Content-Type")});
         
        Ext.defer(
           function(p) {
               p.destroy();
           },
           250,
           this,
           [progIndicator]
       );
       // define file system entry
       var fe = new Ext.device.filesystem.FileEntry("/" + fileName, MyApp.app.Fs);
       fe.getEntry({
                
                file: fileName,
                options: {create: true},
                success: function(entry) {
                     
                    // get native file system url
                    // to saved document..will be file://[some path]
                    var fullPath = entry.nativeURL;
                     
                    // write binary data to file
                    entry.createWriter(function(fileWriter) { 
                        fileWriter.write(blob);               
                    });
                     
                    // return path of local file to
                    // callback function
                    if (callback) {
                       callback.call(me,fullPath);
                    }
                     
                },
                 
                failure: function(error) {             
                    Ext.Msg.alert("Transaction Failed (02)", error.message);
                }
        });
    },
    failure: function(error) {
       progIndicator.destroy();
       Ext.Msg.alert("Transaction Failed (03)", error.message);
    }
});
Note that while you’ll be able to test this code on device simulators, the Ext.device.filesystem.FileEntry.getEntry() method will fail if the app is run through desktop Chrome.
Happy coding!

Written by: Steve Drucker
[Cross-Promoted: Druck-I.T.]

No comments:

Post a Comment

About Us

Fig Leaf Software is an award-winning team of imaginative designers, innovative developers, experienced instructors, and insightful strategists.

For over 20 years, we’ve helped a diverse range of clients...

Read More

Contact Us

202-797-7711

Fig Leaf Software

1400 16th Street NW
Suite 450
Washington, DC 20036

info@figleaf.com