Working with Data

Everything you see within the controls (on a screen) is data. Text control will display text, Image control will display Image, video control will play video and all of this is data.

Applications store

  • Static data - does not get change over the life of the application.
  • Dynamic data - changes over the life of the application.

Data can reside locally on a device or on a remote server. AVM has a light-weight SQLite database that can persist data locally.

Applications can get data from various sources

  • Static data stored in its files or local database
  • Data from user
  • Data from another application like contact list
  • Data from remote server.

This chapter is about how to work with data using Appemble AVM. Pre-requisite for this chapter is basic knowledge about controls.

What you will learn in this chapter

Attributes defining data source for control Attributes defining data source for screen
Display Static data Fetch local data in XMADL control element
Fetch local data in XMADL screen element Fetch data from a previous screen
Fetch remote data in XMADL screen element Fetch remote data in XMADL control element
Save data to local SQLite Save data to remote
Order of applying a data source to the control Data Security
Working with local content database  

Attributes defining Data Sources

Attributes defining data source for control

The XMADL element <control> has several attributes that help define the data attributes (source, format and size) for the control.

Attribute Description
default_value Static data is displayed using this attribute
field_name When the data is fetched from the previous action, local or remote data source, field_name is used to identify the data relevant for the control. For example, if the previous action passes first_name=’Matt’, last_name=’White’, Gender=’Male’ then the control with field_name ‘first_name’ will display ‘Matt’.
data_type Defines the type of data that the control can accept. For example, for a date field the data_type will be ‘DATE’, See list of data types.
storage_format This helps in interpreting the data read from the data source (default value, previous action, local data, remote data). For example, if ‘01/31/2013’ is read for a date field and the storage_format is ‘MM/dd/yyyy’, then month will be 01, day will be 31 and year will be 2013.
format_type This helps in formatting the data before displaying it on the control or helps in interpreting the data while reading from the screen. For example, for a date field, if the format_type is ‘mm/DD/yyyy’, then the control will display the date as ‘01/31/2013’ when the month is January, day is 31 and year is 2013. Similarly when reading the data from the control, this format_type is used to extract the fields. For example, when the user enters the date as ‘01/31/2013’ in an edit field, then the date will be read as month = January, day = 31, year = 2013.
size This determines the size of the data that the control can accept. For example if the control name=first_name has a size=4, and the data obtained from the data source is ‘Matthew’, then the control will display only ‘Matt’. Also when accepting the data from the control, only the first 4 chars will be used. So if user enters the first name as ‘Matthew’, then the first_name read from the control will be ‘Matt’.
local_data_source This is used to define SQL statement for reading data from the light weight local database (SQLite) that is part of the application. For example, to select the first_name from the user table, the local_data_source will be a SQL query “Select first_name from user”.
remote_data_source This is URL (Web Address) of the remote server from where the data is fetched. The server response could be an Image, JavaScript Object Notation (JSON). More formats are will be supported in future.
remote_request_type Defines http request type to be made to the server. Values GET, POST, PUT, DELETE
remote_data_format This defines the format of data received back after executing the URL. Values are JSON, IMAGE. Default is JSON.
remote_data_save_locally

This attribute directs AVM to save the remote data locally as well before passing it to the control. If the server response is JSON, AVM will attempt to save the data locally. See section Fetch local data in XMADL control element below.

Note: Local Data is always fetched after the remote data is fetched. So if remote data is first saved into the local database then the local data fetch will get the latest and greatest data.

Attributes defining data source for screen

XMADL element <screen> has attributes using which the data source for the screen can be defined. Once the data is fetched it is applied to all its child controls.

Attribute Description
local_data_source This is a SQL statement for reading data from the light weight local database (SQLite) that is part of the application built using AVM. For example, a screen has 3 child controls, whose field names are first_name, last_name, email. This screen has a local data source=”select first_name, last_name, email from user”. The local data is fetched when the event ON_RESUME_SCREEN occurs. The local data will then be fed to all the three controls with ONE SQL query.
remote_data_source

This is same as the remote_data_source applied to the control element.

If AVM can parse the remote response because it is a pre-defined format, then the remote data can then be applied to the child controls of the screen.

remote_request_type Defines http request type to be made to the server. Values GET, POST, PUT, DELETE
remote_data_format This defines the format of data received back after executing the URL. Its values are JSON, HTML, IMAGE. Default is JSON.
remote_data_save_locally

This attribute directs AVM to save the remote data locally as well before passing it to the control. If the server response is JSON, AVM will attempt to save the data locally. See section Fetch local data in XMADL screen element below.

Note: Local Data is always fetched after the remote data is fetched. So if remote data is first saved into the local database then the local data fetch will get the latest and greatest data.

AVM fetches data defined by local_data_source or remote_data_source on the event ON_RESUME_SCREEN. ON_RESUME_SCREEN event occurs when the screen is first created and whenever the screen is shown once again. For example, while working in the application, a phone call comes and pushes the app to the background. Upon completion of the phone call, the app comes in foreground again and ON_RESUME_SCREEN event occurs. This can trigger fetching the data again (from local and remote data sources).

Display Static data

One of the most common usage of data source is to display static data.

Example 1: Display text “Hello World”

<control type="TEXT" x="10" y="30" width="80" height="25"
            appearance_name="black" word_wrap="1" data_type="VARCHAR"
        default_value="Hello World!">

Example 2: Display labels in a form

<control name="labelfirstname" type="TEXT" x="2" y="3" width="30" height="8"
            appearance_name="black" data_type="VARCHAR"
            default_value="First Name"/>
<control name="labellastname" type="TEXT" x="2" y="12" width="30" height="8"
            appearance_name="black" data_type="VARCHAR"
            default_value="Last Name"/>
<control name="labelemail" type="TEXT" x="2" y="22" width="30" height="8"
            appearance_name="black" data_type="VARCHAR"
            default_value="Email"/>
<control name="labelpassword" type="TEXT" x="2" y="32" width="30" height="8"
            appearance_name="black" data_type="VARCHAR"
        default_value="Password"/>

Example 3: Display logo

<control name="logo" type="IMAGE" x="1" y="1" width="30" height="8"
            appearance_name="black" data_type="VARCHAR"
            default_value="IMAGE:logo.png"/>

Tip

You can use default_value attribute to display mock data while designing an application. Once the screens look satisfactory, then you can start plugging in real data sources using local_data_source or remote_data_source attributes described in the next sections.

Working with local content database

When you copied the template project to your project it came up with a light weight SQLite database. You can find the database at the following location in your project.

  • For Android - yourProject/assets/<yourapp>_content.sqlite
  • For iOS - yourProject/Resources/assets/<yourapp>_content.sqlite

How to open the SQLite Database?

You can open the content SQlite database using a

  • Software for example SQLite Expert that displays the tables and allows you to modify the schema and the content in a nice Graphical User Interface.
  • Using Firefox - On the Firefox you can install SQLite Manager to view the database
  • Command line - You can download command-line shell.
  • More resources on Stackoverflow

There are 4 default tables created in the content db. These tables MUST NOT be removed.

  • _alarm_manager (cannot be changed or removed)
  • _image_manager (cannot be changed or removed)
  • android_metadata (cannot be changed or removed)
  • _properties (can be modified).

You can create your content tables based on your data model.

Example

CREATE TABLE [user_details] (
       [lastname] VARCHAR(50), [firstname] VARCHAR(50), [email] VARCHAR(80), [password] VARCHAR(30));

Fetch local data

Fetch local data in XMADL control element

A local data source is defined to fetch data in a control from local SQLite database table using a query. You have to create the data tables in your local content SQLite(Android - yourProject/assets/yourapp_content.sqlite, iOS - yourProject/Resources/assets/yourapp_content.sqlite).

Most common use case is to fetch data for GROUP controls like LIST or CONTROL_GROUP to fetch data for all their child control.

Example 1: In the example below, the LIST control has a local_data_source that can fetch multiple rows from the local database. Each row will create a new list item. The fetched data will be mapped to the child control using its field_name.

<control type="LIST" x="0" y="0" width="100" height="100"
    appearance_name="black" data_type="VARCHAR"
    local_data_source="select list_item_id as _id, item, category
    from myshopping_list order by category"
    on_empty_show="show_when_list_is_empty">

    <!-- Child controls of list -->
    <control type="TEXT" x="3" y="2" width="27" height="7"
        appearance_name="black" data_type="VARCHAR" field_name="item" />
    <control type="TEXT" x="35" y="2" width="50" height="7"
        appearance_name="black" data_type="VARCHAR" field_name="category" />
</control>

Pre-requisite for the above example

Table called myshopping_list has been created. It has fields list_item_id, item, category.

If you are not familiar with queries and creating tables in a database, go to sql cheat sheet.

Note

  • It is required that either the column names in the table match with the field names used in the attribute field_name or column names are aliased and match the field names..
  • Though it is allowed to define local_data_source for any control, it is recommended to fetch the data once by defining screen’s local_data_source and then populating all the child controls at once rather fetching data individually for every control.

Example 2: Fetch email address from user table.

<control type="TEXT" appearance_name="18" data_type="VARCHAR" field_name="useremail"
        x="5" y="5" width="45" height="5"
                        local_data_source="select useremail from userdetails "/>

Pre-requisite for the above example - Data table userdetails exists. It has fields a column “useremail”.

Fetch local data in XMADL screen element

When displaying the screen, it is often required to populate the controls with data. The data can be fetched from the local data source.

For example, if the screen shows user’s profile and the data is stored in the local database, then it can be fetched and displayed on the screen. The screen’s attribute local_data_source is an SQL statement. The fetched SQL data is mapped to the child controls using the control’s field_name. In the code sample below, the local data source fetches email and password. The controls with field_names email and password are filled with the data.

<screens>
    <screen name="userprofile" scroll="VERTICAL"
            local_data_source ="select email, password from user_details where email=&apos;&lt;email&gt;&apos;">
        <controls>
            <control name="editemail" type="TEXT" x="35" y="22" width="50" height="8"
                    appearance_name="black" data_type="VARCHAR"
                    field_name="email" default_value="" size="80"/>
            <control name="editpassword" type="PASSWORD" x="35" y="32" width="50" height="8"
                    appearance_name="edit_box" data_type="VARCHAR"
                    field_name="password"
                    default_value="" size="80"/>
                </controls>
        </screen>
   </screens>

In the above example look at the query statement. where email="<email>" has been replaced by &apos;&lt;email&gt;&apos;. xml has special reserved characters which need to be escaped.

Note

The local_data_source for a screen should be defined such that it fetches only ONE row from the database. If multiple rows are fetched, only the data from the first row is be applied to the controls.

Fetch data from a previous screen

A screen can be invoked from another screen using the action NEXT_SCREEN. This action can collect the data from the previous screen if its attribute input_parameter_list is defined. The input_parameter_list is list of (comma separated) field_names identifying the child controls from where the data is to gathered. The action then makes this data available to the next screen using the attribute target_parameter_list. If target_parameter_list is not defined, it is same as input_parameter_list. target_parameter_list allows you to map field_name in one screen to a different field_name in another screen. The child controls of the new screen get the data if their field_name matches the parameter name contained in the action’s target_parameter_list.

The following example shows a code snippet of the registration screen. Here on tap of PUSHBUTTON, the action NEXT_SCREEN is invoked. This action fetches the data from the current screen for field_name(s) defined in the input_parameter_list. Then the action creates the new userprofile screen. The userprofile screen displays the data in its child controls whose field_name is lastname, firstname, email and password by taking the data from the previous action NEXT_SCREEN.

<control name="savebutton" type="PUSHBUTTON" x="10" y="50" width="80" height="10"
        appearance_name="blue_button" data_type="VARCHAR" word_wrap="1" default_value="Save and display values in Profile" >
    <!-- attaching action to this control -->
    <actions>
        <action event_list="TAP" action_name="NEXT_SCREEN" target="userprofile"
                input_parameter_list="lastname, firstname, email, password">
            <action event_list="TAP" action_name="CLOSE_SCREEN" />
        </action>
    </actions>
</control>

input_parameter_list can be used to pass the following:

data from controls Data can be fetched from the controls on the screen using field_name, and can be passed to the next screen. For example: input_parameter_list=”lastname, firstname, email, password” will fetch the data from controls whose field_name is lastname, firstname, email and password. The value will be passed to the next screen
Constants

You can pass constants values from one screen to the controls in another screen. Usage: input_parameter_list=”CONSTANT:1, CONSTANT:Screen 1 Title”

target_parameter_list=”title_id, title”

Global variables

You can pass values of global variables to the next screen. Global variables can be defined in _properties table in

yourProject/assets/yourproject_content.sqlite for Android

yourProject/Resources/assets/yourproject_content.sqlite for iOS

They can be accessed by GLOBAL:<name of variable>. For example by giving the following

input_parameter_list=”GLOBAL:var1, var2, var3”

target_parameter_list=”var1, var2, var3”

var1 will contain the value stored in the _properties table for key = ‘var1’

query You can fetch a value from the database and pass it to the next screen. Usage example: input_parameter_list=”select email from userprofile,username” target_parameter_list=”email, username”

Note: The attribute “target” of the action NEXT_SCREEN can also contain the above parameters and are evaluated before the next screen in created.

Fetch data from GLOBAL properties

The content database comes with a predefined table _properties It is used to store global variables. It has two columns key and value. Global Properties can be added either statically by opening the table and adding key/value pairs or dynamically using the action SAVE_GLOBAL_PROPERTIES.

Example

Add the follownig row in the _properties table of the content database 

key value
url http://test.example.com

Now define a remote_data_source as shown below.

remote_data_source="GLOBAL:url/getUserDetails?name=John&lastname=Doe"

The remote_data_source will be evaluated to http://test.example.com/getUserDetails?name=John&lastname=Doe”. Advantage of saving the url in Global Properties is when the server is switched from test server to production, the url needs to be updated only at one place.

Fetch Remote Data

Fetch remote data in XMADL screen element

It is quite common that the data is present on the remote server and is to be fetched for displaying on a screen. This can be achieved by defined the attribute remote_data_source. Remote Data Source is a URL that is sent to the server and the response will be received in the format specified by remote_data_format. The formats IMAGE and JSON are supported by AVM. For example remote_data_format=JSON and remote_data_source=”http://www.swimdash.com/swimdash/index/index/format/json/category/3” is expected the fetch the data in JSON format. Once the data is fetched, it is attempted to be saved to the local database if the attribute remote_data_save_locally is set to “true”.

In the example below, server is contacted using the URL=http://swimdash.com/swimdash/index/index/category/3/format/json.

<screens>
    <screen name="remotelist" screen_type="SCREEN" menuOrder="1" menuName="Remote" initial_layout="PORTRAIT" allowed_layouts="BOTH"
            width="100" height="100" remote_data_format="JSON"
            remote_data_source="http://swimdash.com/swimdash/index/index/category/3/format/json"
            remote_request_type="GET" remote_data_save_locally="true">

        <controls>
            <control name="remotelist" type="LIST" x="0" y="0" width="100" height="100" permission="READONLY"
                    appearance_name="black" data_type="CURSOR"
                    local_data_source="SELECT sdid as _id, title, logo, (substr(start_date, 7,4) || '-' || substr(start_date, 1,2) || '-' ||  substr(start_date, 4,2) ) as start_date, (substr(end_date, 7,4) || '-' || substr(end_date, 1,2) || '-' ||  substr(end_date, 4,2) ) as end_date FROM featured order by start_date desc">

                <!-- Child controls of list -->
                <control type="IMAGE" x="1" y="1" width="12" height="10" permission="READONLY"
                        appearance_name="black" data_type="VARCHAR" field_name="logo" size="255"  />
                <control type="TEXT" x="20" y="1" width="60" height="7" permission="READONLY"
                        appearance_name="black" data_type="VARCHAR" field_name="title" size="255" />
                <control type="TEXT" x="20" y="8" width="35" height="7" permission="READONLY"
                        appearance_name="black" data_type="DATE" format_type="EEE,MMM d,yyyy" field_name="start_date" size="255" storage_format="yyyy-MM-dd" />
                <control type="TEXT" x="57" y="8" width="5" height="7" permission="READONLY"
                        appearance_name="black" data_type="VARCHAR" default_value="to" />
                <control type="TEXT" x="20" y="15" width="35" height="7" permission="READONLY"
                        appearance_name="black" data_type="DATE" format_type="EEE,MMM d,yyyy" field_name="end_date" size="255" storage_format="yyyy-MM-dd" />
            </control>
        </controls>
    </screen>
</screens>

The sample server response is

featured: [
    {
        title: "SCSC International Meet 2011",
        start_date: "06/16/2011",
        end_date: "06/19/2011",
        logo: "http://www.swimdash.com/repos/996/10002/images/SCSC logo blue bell and text yellow back-big.JPG",
        sdid: 10002,
        getdetails_url: "/swimdash/index/getdetails/format/json",
        meet_hostlsc: "PACIFIC",
        meet_class: 2
    },
    {
        title: "SCSC Seniors Meet 2012",
        start_date: "01/28/2012",
        end_date: "01/29/2012",
        logo: "http://www.swimdash.com/repos/996/10001/images/SCSC logo blue bell and text yellow back-big.JPG",
        sdid: 10001,
        getdetails_url: "/swimdash/index/getdetails/format/json",
        meet_hostlsc: "PACIFIC",
        meet_class: 2
    }
]

After receiving the response, AVM attempts to save this data locally in the table “featured”. Once the data is saved locally, the LIST control fetches the data from the local database using the SQL defined in the attribute local_data_source and displays as two rows. The fetched columns must match the field_name of the child control of LIST control. Please refer to Create list and fetch data from remote data source to see a working example.

Fetch remote data in XMADL control element

The remote_data_source can be defined for a control as well. Usually it is defined for the controls whose images are to be fetched from the remote server. The images fetched from the remote server are cached by AVM for a certain time (a user setting). So for the first time, the images may take some time to load but after that they are fetched from the local device unless they are expired. Fetching data from a remote server is a time consuming task. It is generally recommended to minimize the remote calls unless absolutely needed.

Note

  • Remote data can always be cached to the local database.
  • Remote data is always fetch first. If remote_data_save_locally is “true” and the server response is a known format (like JSON) then the remote data is saved locally as well. Then the local data is fetched and this way local data fetch will result is fetching the most recent data.

Difference between applying data source to a screen or to a control

When the data source (local_data_source and remote_data_source) is applied to a screen, the fetched data is applied to all its child controls. However, when the data source is defined for the control, the fetched data is applied only to that control and its children. It is optimal to assign data source to a screen. Exception: LIST control - A list control has a local data source so that its rows can be fetched from the table in the local database. When the list is scrolled, AVM fetches the needed data from the database automatically.

Save Data

Save data to local SQLite

User inputs can be saved locally using an action EXECUTE_SQL.

<control name="savebutton" type="PUSHBUTTON" x="10" y="50" width="80" height="10"
         appearance_name="blue_button" data_type="VARCHAR" word_wrap="1" default_value="Save" >
     <!-- attaching action to this control -->
    <actions>
        <action event_list="TAP" action_name="EXECUTE_SQL"
                target="insert into user_details(lastname, firstname, email, password)
                VALUES(&apos;&lt;lastname&gt;&apos;,&apos;&lt;firstname&gt;&apos;,
                &apos;&lt;email&gt;&apos;,&apos;&lt;password&gt;&apos;)"
                input_parameter_list="lastname, firstname, email, password" >
        </action>
    </actions>
</control>

In the above example, when the user taps on the button “Save”, the action “EXECUTE_SQL” is triggered. AVM fetches the data from the controls whose field_name is listed in the input_parameter_list (lastname, firstname, email and password). Then it prepares the SQL “INSERT INTO user_details(lastname, firstname, email, password) values (‘<lastname>’, ‘<firstname>’, ‘<email>’, ‘<password>’). The parameters enclosed in the angular brackets (<>) are first deparameterized, that is their value is fetched. Finally the SQL statement is executed and the data is inserted into the database.

Save data to remote

User inputs can be saved to remote server by calling URL with POST method.

<control name="savebutton" type="PUSHBUTTON" x="10" y="50" width="80" height="10"
         appearance_name="blue_button" data_type="VARCHAR" word_wrap="1" default_value="Save" >
     <!-- attaching action to this control -->
    <actions>
        <action event_list="TAP" action_name="CALL_URL" remote_request_type="POST" run_in_background="true"
                target="http://www.example.com/save_user_profile"
                input_parameter_list="lastname, firstname, email, password">
        </action>
    </actions>
</control>

In the above example, when the user taps on the button “Save”, the action CALL_URL is triggered. AVM fetches the data from the controls whose field_name is listed in the input_parameter_list (lastname, firstname, email and password), prepares the post parameter and makes a URL call to the remote server.

Note

If the parameter run_in_background set to “false”, it may make your application unresponsive until the server responds back.

Order of applying a data source to the control

A control may receive data from multiple data sources. When it is to be updated the following order is applied

  • default_value
  • override if data is available from previous action
  • override if data is available from local data source
  • override if data is available from remote data source

Data Security

TODO