3

Can we Cache Dynamically Created Lists or View till the webservices are called in background. I want to achieve something like the FaceBook App does. I know its possible in Android Core but wanted to try it in Titanium (Android and IOS).

I would further explain it, Consider I have a app which has a list. Now When I open for first time, it will obviously hit the webservice and create a dynamic list.

Now I close the app and again open the app. The old list should be visible till the webservice provides any data.

SSS
  • 1,025
  • 7
  • 17

1 Answers1

1

Yes Titanium can do this. You should use a global variable like Ti.App.myList if it is just an array / a list / a variable. If you need to store more complex data like images or databases you should use the built-in file system. There is a really good Documentation on the Appcelerator website.

The procedure for you would be as follows:

  1. Load your data for the first time
  2. Store your data in your preferred way (Global variable, file system)
  3. During future app starts read out your local list / data and display it until your sync is successfull.

You should consider to implement some variable to check wether any update is needed to minimize the network use (it saves energy and provides a better user experience if the users internet connection is slow).

if (response.state == "SUCCESS") {
    Ti.API.info("Themes successfully checked");
    Ti.API.info("RESPONSE TEST: " + response.value);

    //Create a map of the layout names(as keys) and the corresponding url (as value).
    var newImageMap = {};
    for (var key in response.value) {
        var url = response.value[key];
        var filename = key + ".jpg";   //EDIT your type of the image

        newImageMap[filename] = url;
    }

    if (Ti.App.ImageMap.length > 0) {
        //Check for removed layouts
        for (var image in Ti.App.imageMap) {
            if (image in newImageMap) {
                Ti.API.info("The image " + image + " is already in the local map");
                //Do nothing
            } else {
                //Delete the removed layout
                Ti.API.info("The image " + image + " is deleted from the local map");
                delete Ti.App.imageMap[image];
            }
        }
        //Check for new images
        for (var image in newImageMap) {
            if (image in Ti.App.imageMap) {
                Ti.API.info("The image " + image + " is already in the local map");
                //Do nothing
            } else {
                Ti.API.info("The image " + image + " is put into the local map");
                //Put new image in local map
                Ti.App.imageMap[image] = newImageMap[image];
            }
        }
    } else {
        Ti.App.imageMap = newImageMap;
    }

    //Check wether the file already exists
    for (var key in response.value) {
        var url = response.value[key];
        var filename = key + ".png"; //EDIT YOUR FILE TYPE

        Ti.API.info("URL: " + url);
        Ti.API.info("FILENAME: " + filename);

        imagesOrder[imagesOrder.length] = filename.match(/\d+/)[0]; //THIS SAVES THE FIRST NUMBER IN YOUR FILENAME AS ID

        //Case1: download a new image
        var file = Ti.Filesystem.getFile(Ti.Filesystem.resourcesDirectory, "/media/" + filename);

        if (file.exists()) {
            // Do nothing
            Titanium.API.info("File " + filename + " exists");
        } else {
            // Create the HTTP client to download the asset.
            var xhr = Ti.Network.createHTTPClient();

            xhr.onload = function() {
                if (xhr.status == 200) {
                    // On successful load, take that image file we tried to grab before and
                    // save the remote image data to it.
                    Titanium.API.info("Successfully loaded");
                    file.write(xhr.responseData);
                    Titanium.API.info(file);
                    Titanium.API.info(file.getName());
                };
            };

            // Issuing a GET request to the remote URL
            xhr.open('GET', url);
            // Finally, sending the request out.
            xhr.send();
        }
    }

In addition to this code which should be placed in a success method of an API call, you need a global variable Ti.App.imageMap to store the map of keys and the corresponding urls. I guess you have to change the code a bit to fit your needs and your project but it should give you a good starting point.

Robin Ellerkmann
  • 2,083
  • 4
  • 29
  • 34
  • How can I manage images in this. My list has images as well which re remotely stored. In a web environment the brower would have cached the image or in phonegap. But what happens in titanium – SSS Nov 05 '14 at 12:56
  • 1
    In Titanium you have to iterate over the response of your API call. Then you store every image in a directory you choose. I will provide some code later. – Robin Ellerkmann Nov 05 '14 at 13:19
  • I am eagerly waiting for the image caching code. I was able to cache webservices in db. – SSS Nov 06 '14 at 05:07
  • Bad idea! it's a very bad practice to keep your own objects on Ti.App - you're doing what's referred to as "Crossing the bridge" and it bad for both the performance and the memory of your app. – developer82 Nov 06 '14 at 10:24
  • So do you have a better idea to store a map of your image ids to prevent the app from downloading them every time even when they didnt change? In my app there are neither performance nor memory problems occurring. – Robin Ellerkmann Nov 06 '14 at 10:48
  • 1
    Use some kind of persistence - save to sqllite, serialize to file, use noSQL db. and for storing global parameters in your app encapsulate in commonJS - it's even recommended in Appcelerator docs as a best practice. – developer82 Nov 06 '14 at 12:22
  • Ok, I didnt know that. I only have about 30 images in my app, maybe thats why I have no problems. For the OP it would be the best to use my structure but store the values properly as @developer82 proposed. – Robin Ellerkmann Nov 06 '14 at 12:24
  • @RobinEllerkmann I also recommend to you to stop storing values on titanium proxy objects - you can never have too many improvements to your app. recommended reading: http://www.yydigital.com/blog/2012/6/18/The_Toll_On_The_Kroll_Bridge – developer82 Nov 06 '14 at 13:49
  • @RobinEllerkmann Thanks for the code. But this is okay for small image set. What If I got a bigger image set. That would increase the app size as well. I want something to buffer my view in Titanium. I have up voted your answer as it really is a useful code but in small scenario. – SSS Nov 07 '14 at 06:29
  • @developer82 I would like to know if Titanium Buffers images on its own. Currently I have a list which has images. On first load I can see the images take a bit time to show. But on 2nd load the images are seen immediately. Does that mean titanium caches them just like web browser. If so that even that would suffice me. – SSS Nov 07 '14 at 06:31