Development - Titanium: Difference between revisions

From EPOD
(v0.2 - Expanded on App and Program Heirarchy, Timed Processes and Database sections)
(Added serious amounts of Style documentation)
Line 83: Line 83:
  P:\EPOD\_Development\Documentation\Android Client\index.html
  P:\EPOD\_Development\Documentation\Android Client\index.html
   
   
=== Program Folder Heirarchy ===
=== Program Folder Hierarchy ===
Under ePODAndroid:
Under ePODAndroid:
* ''CHANGELOG.txt'' - All versions and changes made for the application. Keep this file updated whilst changes are being made. A formal new version will be added when files are checked in. Check in all files with descriptive notations. tiapp.xml should be checked in with the fill comment from this file.
* ''CHANGELOG.txt'' - All versions and changes made for the application. Keep this file updated whilst changes are being made. A formal new version will be added when files are checked in. Check in all files with descriptive notations. tiapp.xml should be checked in with the fill comment from this file.
Line 108: Line 108:
It is imperative that each text item is placed into each of these files. Then translation can be added for different languages as and when required.
It is imperative that each text item is placed into each of these files. Then translation can be added for different languages as and when required.


==== platform folder ====
==== Platform folder ====
This folder contains the preferences or settings applicable to each specific platform. The standard Apple, Android and Titanium documentation should be consulted to ascertain the usage and how these are maintained.
This folder contains the preferences or settings applicable to each specific platform. The standard Apple, Android and Titanium documentation should be consulted to ascertain the usage and how these are maintained.


Line 115: Line 115:
** Resolution (hdpi, mdpi, ldpi)
** Resolution (hdpi, mdpi, ldpi)
** orientation (land, port)
** orientation (land, port)
** widescreen ratio (long, notlong)
** wide-screen ratio (long, notlong)


* ''Database'' - The DAL (Data Access Layer). These are functions and objects that are used to directly affect or access data from the database. All objects are documented as part of the Namespace Database and in specific classes for each DAL object.
* ''Database'' - The DAL (Data Access Layer). These are functions and objects that are used to directly affect or access data from the database. All objects are documented as part of the Namespace Database and in specific classes for each DAL object.
Line 146: Line 146:
* app.js -  This is the start point for the entire application.
* app.js -  This is the start point for the entire application.


=== Application Heirarchy ===
=== Application Hierarchy ===
This section covers how the application calls each screen in a standard flow. Unless specified differently, each element is part of the UI namespace. All of these items are documented as part of the Project documentation in  
This section covers how the application calls each screen in a standard flow. Unless specified differently, each element is part of the UI namespace. All of these items are documented as part of the Project documentation in  
file:///10.43.0.21/Projects/EPOD/_Development/Documentation/Android%20Client/index.html - paste this link into your browser window to begin exploring the documentation.
file:///10.43.0.21/Projects/EPOD/_Development/Documentation/Android%20Client/index.html - paste this link into your browser window to begin exploring the documentation.
Line 206: Line 206:
The database decides whether it needs to be updated based on  
The database decides whether it needs to be updated based on  
* the version in the database
* the version in the database
* whether this is a first logon
* whether this is a first log-on
* whether the version requires a database update.
* whether the version requires a database update.


Line 223: Line 223:


The Login process checks the parameter and re-downloads all data required (as if it's a first login)
The Login process checks the parameter and re-downloads all data required (as if it's a first login)
=== Styling Objects ===
{{warning}} Describe the problem and solution
* Using style.js - loaded into Ti.App.style, so all the methods are available for calling through that.
* How to add new styles and the issues doing so.
** _land styles - These should be created if you want the device to move the object on orientation change, and both styles should contain the property obsRestyle = true.
** Care taken when specifying element, need to null them on orientation changes
* Use of resMod/resModX
* Standard controls with Create functions available that 'overload' the standard UI styles:
** Label
** Picker
** Button
** Table
** Table Row
** View
** ScrollView
** ImageView
** Tab
** Slider
** Switch
** TabGroup
** Table View
** Table View Row
** Text Area
** Text Field
** win - Window
* Standard Styles
** {{Note}} Most styles also have specific Landscape versions created (_land), which are used automatically when the device changes orientation.
** small/smaller/medium/larger/large - font size helper classes
** left/right - text/object horizontal alignment helper classes
** generalButton - sets the display characteristics of a general button. Used in conjunction with positioning classes, as follows:
*** btnSplitBottom
*** btnSplitBottom_land
*** btnBottom
*** btnBottom_land
*** btnSplitMiddle
*** btnSplitMiddle_land
*** btnMiddle
*** btnTop
*** btnScan
*** btnLeft
*** btnCenter
*** btnRight
** generalText/wideText - full-width positioning
** halfText - half-screen width text box positioning (right-hand side)
** generalLabel - general label styling
** tableHead - header for a table or a title for a screen.
** tableRow - general styling for a row, taking into account resolution modifiers for size.
** evenRow - slight background styling for even rows.
** tableView_Status/_A/E/I/X/C - used to format the row based on the status of the order, or change status after receipt. Used in Job List.
** settingsRow - unused as yet.
** portraitWindow/landscapeWindow/anyWindow - basic settings for any type of window. Always use anyWindow
** instrLabel - class for instructions label on Job Details - should be an ID!
** tabContainer/tabDetails/tabProducts/tabNotes/tabInfo/tabPreworkActivities/tabMCRefs - generic tab items
** checkedBox/unCheckedBox - classes used by custom checkbox object.
** tabOn/tabOff - classes used by custom Tab object
** productTable - {{warning}}
** scanText/scanTextBtn - {{warning}}
** popupWinView - used for popup window views
** scrollViewTable - used for mainly full-screen views that scroll vertically.
** scrollViewRow - used for the above.
** claused/cancelled/normal - used for Signature - container clausing.
* {{warning}} custom controls
** Custom Tab
** Checkbox
** UDF - User-defined field object
ID naming conventions:
* The window to which this element belongs, plus '_', plus the ID.
Example:
* winMine_txtBlah
Iterating fields (for example in a table) would be ID'd with the iteration number:
* winMine_lblBlah1
* {{warning}} Vehicle checks - configurable fields and how to use them.
* {{warning}} Scrolling views and why they're better and worse than a table.
=== Other ===
{{warning}} entire section needs expanding.
* Include files once - describe why
* Describe synchronous and asynchronous parts of the code, and why return and callbacks are your friends.
* When debugging on emulator and you want to pick up latest chjanges, you could click the run button again in Titanium. Faster can be clicking on the app within the emulator - it will reload almost every change (that has been saved). Sometimes it fails though.
* above, when running again from titanium, get lots of errors regarding can't build because file is in use. You can try stopping previous background tasks, or you can persevere - usually picks up again after a few goes. Stopping and starting Titanium resolves lots of things...
* Preference changes anf i89n (multilingual) changes do NOT get picked up when restarting the app from the emulator. In fact, sometimes you may need to force this by cleaning the project and rebuilding, then installing from Titanum again.
* adb can timeout if left for a while. If you start the app on the emulator and it hangs, that's probably what happened. Start the app from Titanium. If that doesn't work, reset adb from DDMS. If that doesn't work, exit the emulator, the start the app from titanium - should load another emulator. If that doesn't work, restart your PC.
* {{Warning}} add others here.


=== Notation ===
=== Notation ===
Follow standard notation as follows:
Follow standard variable notation as follows:
* global - preceded with 'g'
* global - preceded with 'g'
* variables preceded with 3-character type, for example:
* variables preceded with 3-character type, for example:
Line 361: Line 271:
** Set the window object to null;
** Set the window object to null;
** Set the vars object to null;
** Set the vars object to null;
* Close and null DB and RS objects after use, or you get runtime errors.
Example:
vars.winMine.addEventListener("close", function () {
    Ti.App.removeEventListener('OrientationChangeOBS', evtOrientationChange);
    // Sets all the objects to null - is this enough to dispose correctly?
    // If not, we'd need to loop through...
    vars=null;
    // Possibly run some callback function or other processing here.
});
 
=== Styling Objects ===
Ti.UI objects are used to add buttons, labels, windows etc. Object arrays are used to define the properties of that object, such as positioning and styling information.
 
Titanium supports styling through specifying a series of identifying properties directly against an individual variable. It does not support reusable generic styling and restyling on demand, only at runtime.
 
To allow for a greater reuse of styling parameters (classes) and restyling (predominantly on orientation change, which must be handled manually in Titanium, the style object was created, placed into Ti.App.style. This is defined in Style.js.
 
This represents a series of reusable, individual ID and bespoke customer classes that are applied to items automatically at creation. It also handles identifying these objects more clearly so that methods of this object can be used to force a restyle at certain events.
 
Style types are:
* Reusable Class - defined in Ti.App.style.styles object.
* Styling for specific ids - defined in Ti.App.style.ids.
* Customer-specific classes and ids - defined in Ti.App.style.configItems, that overloads classes and ids if they exist.
 
==== Adding and Amending Classes ====
 
New styles are added by adding a new named object to the styles, ids of configItems objects, as follows:
 
Ti.App.styles={
    myExistingStyle : {
        left : "1%",
        top : "50%"
    },
    myNewStyle : {
        left : "2%",
        top : "51%"
    }
}
 
Landscape styles are used in preference when styling or restyling an object, depending on the orientation of the device. This is calculated in Style.js and recalculated whenever an orientation change event fires. When this fires, this in turn generates an application event that can drive a listener in a Ti.UI.window or Ti.UI.tabGroup object, if created, which typically restyles all objects under the window, using Ti.App.style.restyleItems.
 
Landscape classes and styles that have landscape forms (in styles, ids and configItems) are defined as follows:
 
Ti.App.styles={
    myExistingStyle : {
        left : "1%",
        top : "50%",
        obsRestyle : true
    },
    myExistingStyle_land : {
        left : "1%",
        top : "30%",
        obsRestyle : true
    }
}
 
{{Note}} The restyle function overloads properties from the new style onto the existing object. In the example above, if the object using this class myExistingStyle is restyled on an orientation change to landscape, the only change will be that the top property will change from 50 to 30 percent. Consider the following example:
 
Ti.App.styles={
    myStyle : {
        left : "1%",
        top : "50%",
        width : "98%",
        obsRestyle : true
    },
    myStyle_land : {
        right : "1%",
        top : "30%",
        width : "49%",
        obsRestyle : true
    }
}
 
The properties of the object are not removed upon restyle, so the result of restyling from portrait to landscape would result in an object with the properties as follows:
 
    {
        left : "1%",
        right : "1%",
        top : "50%",
        width : "98%",
        obsRestyle : true
    }
 
This may not be what was intended. It should be defined like this:
Ti.App.styles={
    myStyle : {
        left : "1%",
        right : null,
        top : "50%",
        width : "98%",
        obsRestyle : true
    },
    myStyle_land : {
        left : null,
        right : "1%",
        top : "30%",
        width : "49%",
        obsRestyle : true
    }
}
 
If the device starts in landscape orientation, the landscape class will be used which will look correct. Only when it is reoriented from one to the other will the problem become evident. This is why the properties that are not required are nulled if they are to be overwritten.
 
{{Note}} If no restyle is specified, the object will not restyle at all (except when the preference Style property is changed, when everything is forced to be restyled) it won't restyle at all, regardless of the presence of an "_land" class.
 
The class also supports resizing pixel sizes if required, based on the resolution of the device. This is largely most effective on font and row height properties, where percentage heights are difficult to gauge.
 
This is achieved using Ti.App.resMod, as follows:
 
Ti.App.styles={
    myStyle : {
        left : null,
        height: (100*Ti.App.resMod),
        top : "30%",
        width : "49%",
        obsRestyle : true
    }
}
 
Another resolution modifier, Ti.App.resModX, exists for width modifications. Note that this is normally only required for specific height and width views - the signature imageView for example.
 
These styles are automatically applied to UI objects that are created through Ti.App.style.create<Object> methods, such as Ti.App.style.createLabel.
 
==== Classes Available ====
Standard Classes available are:
* small/smaller/medium/larger/large - font size helper classes
* left/right - text/object horizontal alignment helper classes
* generalButton - sets the display characteristics of a general button. Used in conjunction with positioning classes, as follows:
** btnSplitBottom
** btnBottom
** btnSplitMiddle
** btnMiddle
** btnTop
** btnScan
** btnLeft
** btnCenter
** btnRight
* generalText/wideText - full-width positioning
* halfText - half-screen width text box positioning (right-hand side)
* generalLabel - general label styling
* tableHead - header for a table or a title for a screen.
* tableRow - general styling for a row, taking into account resolution modifiers for size.
* evenRow - slight background styling for even rows.
* tableView_Status/_A/E/I/X/C - used to format the row based on the status of the order, or change status after receipt. Used in Job List.
* settingsRow - unused as yet.
* portraitWindow/landscapeWindow/anyWindow - basic settings for any type of window. Always use anyWindow
* instrLabel - class for instructions label on Job Details - should be an ID!
* tabContainer/tabDetails/tabProducts/tabNotes/tabInfo/tabPreworkActivities/tabMCRefs - generic tab items
* checkedBox/unCheckedBox - classes used by custom check-box object.
* tabOn/tabOff - classes used by custom Tab object
* productTable - A class specifically for tables
* scanText/scanTextBtn - used within the Barcode object
* popupWinView - used for pop-up window views
* scrollViewTable - used for mainly full-screen views that scroll vertically.
* scrollViewRow - used for the above.
* claused/cancelled/normal - used for Signature - container clausing.
 
==== Creating Objects ====
Standard Ti.UI objects with Ti.App.style.create<Object> functions available that 'overload' the standard UI styles are:
* Label
* Picker
* Button
* Table
* TableRow
* View
* ScrollView
* ImageView
* Tab
* Slider
* Switch
* TabGroup
* TableView
* TableViewRow
* TextArea
* TextField
* Window
 
Each object creation function allows you to specify:
* The id of the object
* The class to be applied. Several can be specified, space-delimited.
* An object array containing in-line styles to apply.
 
The id of the object is typically defined as the window to which this element belongs, plus '_', plus the variable name.
* <window>_<varName>
Example:
* winMine_txtBlah
Iterating fields (for example in a table) would be ID'd with the iteration number:
* <window>_<varName><iterationVariable>
Example:
* winMine_lblBlah1
* winMine_lblBlah2
 
For example:
var vars={};
vars.winSelf=Ti.App.createWindow('winSelf','anyWindow',{});
vars.vwSelf=Ti.App.createView('winSelf_vwSelf','',{});
vars.winSelf.add(vars.vwSelf);
vars.vwSelf.add(Ti.App.createLabel('winSelf_lblText','generalLabel',{
    text : "Enter Text",
    top : "50%",
    left : "1%",
    width : "48%"
}));
vars.txtText=Ti.App.createLabel('winSelf_txtText','generalText',{
    top : "50%",
    left : "51%",
    width : "48%"
}));
vars.vwSelf.add(vars.txtText);
vars.winSelf.open();
* This example shows a variety of creation and opening mechanisms.
* It also shows a variety of styles applied, from Class, ID and in-line.
* Typically, a variable does not need to be created separately if it is never referenced again - see the creation of the label above.
* The example also shows the use of the vars variable, typically used to make disposing of objects quicker on closing of a window (see Garbage Collection)
 
==== Hierarchy of Classes ====
* Class (last takes precedence over first)
* Device-Specific Class (Hi-resolution, Orientation - last takes precedence over first)
* Style-specific Class (last takes precedence over first)
* Style-specific Device-Specific Class (Hi-resolution, Orientation - last takes precedence over first)
* ID
* Device-Specific ID (Hi-resolution, Orientation)
* Style-specific ID
* Style-specific Device-Specific ID (Hi-resolution, Orientation)
* In-line properties (highest precedence)
 
==== Custom Controls ====
Custom controls have been created as part of the style object, in order to simplify the creation of a complex series of options, or to create an object that Titanium doesn't provide.
* Custom Tab - used when a tab object is required within a window, rather that outside, like TabGroup.
* Checkbox - a standard check-box, that changes from a cross to a tick, and vice versa.
* UDF - User-defined field object. This is a object of many fields, defined by an XML configuration, e.g. Vehicle Checks.
 
* {{warning}} customTab and how to use it.
 
* {{warning}} Vehicle checks - UDF configurable fields and how to use them.
 
* {{warning}} Scrolling views and why they're better and worse than a table.


=== Source Control ===
=== Source Control ===
Line 368: Line 513:
Click ''Synchronise'' when using for the first time - always synchronise changes before a build.
Click ''Synchronise'' when using for the first time - always synchronise changes before a build.


The legend on the filelist should indicate whether:
The legend on the file-list should indicate whether:
* The local file is changed and needs committing.
* The local file is changed and needs committing.
* The SVN file has changes in that you need to incorporate into your local files.
* The SVN file has changes in that you need to incorporate into your local files.
Line 454: Line 599:
** What you can do in it
** What you can do in it
* DDMS and what it can do for you.
* DDMS and what it can do for you.
=== Other ===
This section details observations, suggestions and potential pitfalls that may aid the Titanium developer.
{{warning}} entire section needs expanding.
* Include files once - describe why
* Describe synchronous and asynchronous parts of the code, and why return and callbacks are your friends.
* When debugging on emulator and you want to pick up latest changes, you could click the run button again in Titanium. Faster can be clicking on the app within the emulator - it will reload almost every change (that has been saved). Sometimes it fails though.
* above, when running again from titanium, get lots of errors regarding can't build because file is in use. You can try stopping previous background tasks, or you can persevere - usually picks up again after a few goes. Stopping and starting Titanium resolves lots of things...
* Preference changes and i89n (multilingual) changes do NOT get picked up when restarting the app from the emulator. In fact, sometimes you may need to force this by cleaning the project and rebuilding, then installing from Titanium again.
* adb can time-out if left for a while. If you start the app on the emulator and it hangs, that's probably what happened. Start the app from Titanium. If that doesn't work, reset adb from DDMS. If that doesn't work, exit the emulator, the start the app from titanium - should load another emulator. If that doesn't work, restart your PC.
* Close and null DB and RS objects after use, or you get runtime errors.
* {{Warning}} add others here.


[[Category:WI 287575 EPOD Development and Release Process|020]]
[[Category:WI 287575 EPOD Development and Release Process|020]]

Revision as of 16:43, 5 June 2013

Android Development Environment Setup

Titanium

  • Download and install Titanium.
iOS:
  • Once dpkg file is downloaded, run it, then drag titanium to applications.


Windows Mobile:
  • Double-click the downloaded application and follow the instructions.


  • Run the Titanium application.
  • Select the default workspace, always.
  • Login using your supplied Titanium login details.
  • Install 2.4 SDK through the Help/Install Titanium SDK/Install from Update stream/Release/2.1.4.GA
  • Suggested Titanium theme is Light, UI is Advanced.
  • Set up SVN within Titanium as follows:
  • First time you use the SVN repository (for example, when you import the project), you will be prompted to set it up and select a connector. Choose the top one (SVN Kit 1.2.3)
  • Note Note: downloading: always accept the license agreement. Always restart when prompted.
  • Assumes you have access to the SVN repository on \\10.43.0.21\Projects\EPOD\_Development\SVN\epod
  • iOS:
    • Set up a Server share to 10.43.0.21/Projects and enter the correct username and password.
    • Do this by choosing Add Server, entering smb://10.43.0.21/Projects
    • Then Import a project, and follow the wizard.
    • The SVN URL should be: file:///Volumes/Projects/EPOD/_Development/SVN/epod
    • Enter the username and password you want.


    Windows Mobile:
    • The SVN URL should be: P:/EPOD/_Development/SVN/epod
    • Enter the username and password you want.


  • Choose to search for projects under this folder and import separately.
  • But realistically, you are only interested in ePODAndroid.
  • You can also install RapidSVN.
  • Titanium Module setup

    two ways:

    • Use the Dashboard window to install
    • Click on My Modules
    • Click on install on:
      • barcode
      • paint
      • imageFactory

    OR

    iOS:
    • Note: EXTRACT the zip files into the already-existent Modules directory, don't just leave the zips there. Watch out for Apple overwriting the entire folder rather than merging the two folders.


    Android SDK

    • Download.
    iOS:
    • Install by extracting and copying the folders into the Applications folder.
    • Add to the PATH env variable:
    • from Terminal:
    • vi ~/.bash_login
    • Add:
      • export PATH=$PATH:/Applications/sdk/Platform-tools:/Applications/sdk/tools


    Windows Mobile:
    • Install as normal


    Android Dev Setup

    Run the ADK setup utility (called Android in Platform-tools) Download all info from 4.03 to 2.2, skipping all 3.X variants (no-one really needs Honeycomb).

    XCODE v4.5

    iOS:MAC ONLY

    • Download
    • Login to developer.apple.com with the supplied credentials.
    • Click iOS Dev Center
    • Click Looking for an older version of Xcode? Download Change search to Xcode 4.5 Click link to Xcode 4.5.1, around 1.5 Gb
    • Install
    • Double-click the downloaded file, then double-click the Xcode app inside.
    • Agree to everything.

    Android Programming Guide

    The entire program set is automatically documented from the source code. This is stored in

    P:\EPOD\_Development\Documentation\Android Client\index.html
    
    

    Program Folder Hierarchy

    Under ePODAndroid:

    • CHANGELOG.txt - All versions and changes made for the application. Keep this file updated whilst changes are being made. A formal new version will be added when files are checked in. Check in all files with descriptive notations. tiapp.xml should be checked in with the fill comment from this file.
    • README.md - A descriptive header for the automatically produced source documentation.
    • tiapp.xml - the main controller of the Titanium project. Contains settings, version control, extensions and parameters.
    • i18n - multi-lingual files - see following section
    • platform - platform-specific files - see following section
    • Resources - the main coding area. Here are all the files that a developer would typically maintain or affect. See following sections.

    i18n folder

    Folders in here are organised per system language.

    Each folder contains a 'strings.xml' file, that contains XML tags that have an ID and a piece of text or message. These text snippets should be used for every piece of displayed text within the Android Client application, such as:

    • Labels
    • Button titles
    • All messages

    These labels are accessed through specific functions written for this purpose, wrapping the standard Titanium Multilingual classes, as follows:

    • getLabel(strLabelID) - This function returns the multi-lingual text for the label requested, plus ': '
    • getMessage(strLabelID, pValues) - This function returns the multi-lingual text for the message requested, with the values inserted into the message string at the appropriate point.
    • getString(strLabelID) - This function returns the multi-lingual text for the label requested

    These functions are part of the Ti.App.style class.

    It is imperative that each text item is placed into each of these files. Then translation can be added for different languages as and when required.

    Platform folder

    This folder contains the preferences or settings applicable to each specific platform. The standard Apple, Android and Titanium documentation should be consulted to ascertain the usage and how these are maintained.

    Resources folder

    • Android - Android-specific images, segregated by:
      • Resolution (hdpi, mdpi, ldpi)
      • orientation (land, port)
      • wide-screen ratio (long, notlong)
    • Database - The DAL (Data Access Layer). These are functions and objects that are used to directly affect or access data from the database. All objects are documented as part of the Namespace Database and in specific classes for each DAL object.
      • DBConnection
      • PDA_CONTAINER
      • PDA_DEVICE_TYPE
      • PDA_JOB
      • PDA_JOB_GROUP
      • PDA_LOAD
      • PDA_PHOTO
      • PDA_PRODUCT
      • PDA_REASON_CODE
      • PDA_SERVICE
      • PDA_SERVICE_ACTIVITY
      • EPOD_SERVICE_PRODUCT_MASTER
      • PDA_SERVICE_ACTIVITY_MASTER
      • PDA_SERVICE_PRODUCT
      • PDA_SITE
      • PDA_USER
      • PDA_VEHICLE
      • PENDING_DATA
      • XF_AUDIT
    • images - Generic images are added here then referenced in classes or styling information.
    • System - Reusable objects - documented as part of Namespaces System, UI and Webservices.
    • ui - main screen objects - documented as part of Namespace UI.
    • app.js - This is the start point for the entire application.

    Application Hierarchy

    This section covers how the application calls each screen in a standard flow. Unless specified differently, each element is part of the UI namespace. All of these items are documented as part of the Project documentation in file:///10.43.0.21/Projects/EPOD/_Development/Documentation/Android%20Client/index.html - paste this link into your browser window to begin exploring the documentation.

    App Start (app.js) - create database if required and call login

    |

    Login (Login.js) - user logs in with username, password and vehicle.

    |

    Vehicle Checks (VehicleChecks.js) - if required, vehicle checks are requested here.

    |

    Job List (JobList.js) - this retrieves Loads assigned to the user, shows a list of the jobs and starts timers.

    |

    Cancel a Job (Cancellation.js) - Cancel a job and return to the Job List Job Detail (JobDetail.js) - Show the information of a job and start/travel/arrive.

    |

    Cancel a Job (Cancellation.js) - Cancel a job and return to the Job List Collection (Collection.js) - the collection process Delivery (Delivery.js) - the delivery process Service (SM_Service.js) - the service process

    |||

    Signature Capture (Signature.js) - all processes above request customer and possibly driver signature. Job Photo (DocumentPhoto.js) - optional photo taken of the completed job.

    |

    Send Message Update and return to Job list (through Webservices)

    Timed Services

    These timed processes are started from the Job List screen and control sending:

    • Auto-Update
    • GPS Tracking
    • Pending Messages

    Auto-Update

    Fully documented in class Ti.App.AutoUpdateTimer, in namespace Webservices.

    When a Load is picked up for the user (from Job List) a timer checks every few minutes with the server to see if there have been any changes to the jobs assigned on this load. This process sends the message to the server and processes the response. An application-level event is raised that is processed by the Job List and Job Detail forms (if they are open), which refreshes the data on the screens and lets the user know that changes have happened.

    An auto-update can also be forced by the user from the Job List main menu.

    This timer should be running when in Job List and Job Details only.

    GPS Tracking

    Fully documented in class Ti.App.GeoUpdateTimer, in namespace Webservices.

    If configured, this timed process sends a message on the queue informing the server of the user, vehicle and last known GPS co-ordinates. These are stored on the Vehicle and in tracking on the server.

    This timer should always be running.

    Pending Messages

    Fully documented in class Ti.App.PendingDataTimer, in namespace Webservices.

    Whenever a message is sent to the pending queue, this timer picks up the message and attempts to send it in the background. Any errors are discarded and the message is left if unsuccessful. A successful send automatically attempts to send the next message.

    This timer should always be running.

    Database Details

    The database is created (or updated) at the start of the application, through functions in DBConnection.js, in namespace Database.

    The database is in SQLite3 format.

    The database decides whether it needs to be updated based on

    • the version in the database
    • whether this is a first log-on
    • whether the version requires a database update.

    In order to achieve this:

    • The version must be updated in the Tiapp.xml file.
    • The latest version must be updated in function InstallDB.
    • The last version that required a database update must be updated in function InstallDB.

    The function always stores the version that created or updated the database in table SYSTEM.

    The function checks whether:

    • The stored version on the database is less than the last version that required a database update.
    • If it does, the database is recreated with no data.
    • It updates the latest version of the app in table SYSTEM.
    • It updates a system parameter to show that standing data needs to be completely refreshed.

    The Login process checks the parameter and re-downloads all data required (as if it's a first login)

    Notation

    Follow standard variable notation as follows:

    • global - preceded with 'g'
    • variables preceded with 3-character type, for example:
      • str - String
      • obj - General or custom object
      • lng - Long
      • int - Integer
      • bln - Boolean/Flag
    • Titanium objects should be named as follows:
      • lbl - Label
      • pck - Picker
      • btn - Button
      • tbl - Table
      • tbr - Table Row
      • vw - View
      • chk - Checkbox
      • scr - ScrollView
      • img - ImageView
      • tab - Custom Tab or Tab
      • sli - Slider
      • swt - Switch
      • tgp - TabGroup
      • tvw - Table View
      • tvr - Table View Row
      • txt - Text Area or Text Field
      • udf - User-defined field object (also obj)
      • win - Window

    Note Note: These lists are not comprehensive or infallible. They are intended to guide towards a maintainable, cohesive documentation. Examples:

    • global boolean to control Blah - g_blnBlahFlag
    • text field Blah - txtBlah
    • label for the text field above - lblBlah

    Garbage Collection

    Warning Warning: Although there are issues with garbage collection in Titanium, this information is still being verified. As standard, we should follow these procedures as they will make for easier garbage disposal, whatever the reason.

    • Create an object vars. Note Note: Although this doesn't obey the naming conventions above, it does allow for the easy conversion of existing code, and should be followed until all is complete. After, these conventions will change the name to objVars.
    • All variables should be created under this object in that form. For example, a Blah text field would be declared as
    vars.txtBlah=Ti.App.style.creatTextField('winMine_txtBlah', ' ', {});
    
    • All events should be declared as a function variable, to easily identify them for event removal later. For example:
    vars.AutoupdateEvent = function () {
      vars.winMine.close();
    };
    
    • Upon closing the window:
      • remove any events attached to the window or the app referencing the window, referencing the function object used to create it.
      • Set the window object to null;
      • Set the vars object to null;

    Example:

    vars.winMine.addEventListener("close", function () {
        Ti.App.removeEventListener('OrientationChangeOBS', evtOrientationChange);
        // Sets all the objects to null - is this enough to dispose correctly? 
        // If not, we'd need to loop through...
        vars=null; 
        // Possibly run some callback function or other processing here.
    });
    

    Styling Objects

    Ti.UI objects are used to add buttons, labels, windows etc. Object arrays are used to define the properties of that object, such as positioning and styling information.

    Titanium supports styling through specifying a series of identifying properties directly against an individual variable. It does not support reusable generic styling and restyling on demand, only at runtime.

    To allow for a greater reuse of styling parameters (classes) and restyling (predominantly on orientation change, which must be handled manually in Titanium, the style object was created, placed into Ti.App.style. This is defined in Style.js.

    This represents a series of reusable, individual ID and bespoke customer classes that are applied to items automatically at creation. It also handles identifying these objects more clearly so that methods of this object can be used to force a restyle at certain events.

    Style types are:

    • Reusable Class - defined in Ti.App.style.styles object.
    • Styling for specific ids - defined in Ti.App.style.ids.
    • Customer-specific classes and ids - defined in Ti.App.style.configItems, that overloads classes and ids if they exist.

    Adding and Amending Classes

    New styles are added by adding a new named object to the styles, ids of configItems objects, as follows:

    Ti.App.styles={
        myExistingStyle : {
            left : "1%",
            top : "50%"
        },
        myNewStyle : {
            left : "2%",
            top : "51%"
        }
    }
    

    Landscape styles are used in preference when styling or restyling an object, depending on the orientation of the device. This is calculated in Style.js and recalculated whenever an orientation change event fires. When this fires, this in turn generates an application event that can drive a listener in a Ti.UI.window or Ti.UI.tabGroup object, if created, which typically restyles all objects under the window, using Ti.App.style.restyleItems.

    Landscape classes and styles that have landscape forms (in styles, ids and configItems) are defined as follows:

    Ti.App.styles={
        myExistingStyle : {
            left : "1%",
            top : "50%",
            obsRestyle : true
        },
        myExistingStyle_land : {
            left : "1%",
            top : "30%",
            obsRestyle : true
        }
    }
    

    Note Note: The restyle function overloads properties from the new style onto the existing object. In the example above, if the object using this class myExistingStyle is restyled on an orientation change to landscape, the only change will be that the top property will change from 50 to 30 percent. Consider the following example:

    Ti.App.styles={
        myStyle : {
            left : "1%",
            top : "50%",
            width : "98%",
            obsRestyle : true
        },
        myStyle_land : {
            right : "1%",
            top : "30%",
            width : "49%",
            obsRestyle : true
        }
    }
    

    The properties of the object are not removed upon restyle, so the result of restyling from portrait to landscape would result in an object with the properties as follows:

        {
            left : "1%",
            right : "1%",
            top : "50%",
            width : "98%",
            obsRestyle : true
        }
    

    This may not be what was intended. It should be defined like this:

    Ti.App.styles={
        myStyle : {
            left : "1%",
            right : null,
            top : "50%",
            width : "98%",
            obsRestyle : true
        },
        myStyle_land : {
            left : null,
            right : "1%",
            top : "30%",
            width : "49%",
            obsRestyle : true
        }
    }
    

    If the device starts in landscape orientation, the landscape class will be used which will look correct. Only when it is reoriented from one to the other will the problem become evident. This is why the properties that are not required are nulled if they are to be overwritten.

    Note Note: If no restyle is specified, the object will not restyle at all (except when the preference Style property is changed, when everything is forced to be restyled) it won't restyle at all, regardless of the presence of an "_land" class.

    The class also supports resizing pixel sizes if required, based on the resolution of the device. This is largely most effective on font and row height properties, where percentage heights are difficult to gauge.

    This is achieved using Ti.App.resMod, as follows:

    Ti.App.styles={
        myStyle : {
            left : null,
            height: (100*Ti.App.resMod),
            top : "30%",
            width : "49%",
            obsRestyle : true
        }
    }
    

    Another resolution modifier, Ti.App.resModX, exists for width modifications. Note that this is normally only required for specific height and width views - the signature imageView for example.

    These styles are automatically applied to UI objects that are created through Ti.App.style.create<Object> methods, such as Ti.App.style.createLabel.

    Classes Available

    Standard Classes available are:

    • small/smaller/medium/larger/large - font size helper classes
    • left/right - text/object horizontal alignment helper classes
    • generalButton - sets the display characteristics of a general button. Used in conjunction with positioning classes, as follows:
      • btnSplitBottom
      • btnBottom
      • btnSplitMiddle
      • btnMiddle
      • btnTop
      • btnScan
      • btnLeft
      • btnCenter
      • btnRight
    • generalText/wideText - full-width positioning
    • halfText - half-screen width text box positioning (right-hand side)
    • generalLabel - general label styling
    • tableHead - header for a table or a title for a screen.
    • tableRow - general styling for a row, taking into account resolution modifiers for size.
    • evenRow - slight background styling for even rows.
    • tableView_Status/_A/E/I/X/C - used to format the row based on the status of the order, or change status after receipt. Used in Job List.
    • settingsRow - unused as yet.
    • portraitWindow/landscapeWindow/anyWindow - basic settings for any type of window. Always use anyWindow
    • instrLabel - class for instructions label on Job Details - should be an ID!
    • tabContainer/tabDetails/tabProducts/tabNotes/tabInfo/tabPreworkActivities/tabMCRefs - generic tab items
    • checkedBox/unCheckedBox - classes used by custom check-box object.
    • tabOn/tabOff - classes used by custom Tab object
    • productTable - A class specifically for tables
    • scanText/scanTextBtn - used within the Barcode object
    • popupWinView - used for pop-up window views
    • scrollViewTable - used for mainly full-screen views that scroll vertically.
    • scrollViewRow - used for the above.
    • claused/cancelled/normal - used for Signature - container clausing.

    Creating Objects

    Standard Ti.UI objects with Ti.App.style.create<Object> functions available that 'overload' the standard UI styles are:

    • Label
    • Picker
    • Button
    • Table
    • TableRow
    • View
    • ScrollView
    • ImageView
    • Tab
    • Slider
    • Switch
    • TabGroup
    • TableView
    • TableViewRow
    • TextArea
    • TextField
    • Window

    Each object creation function allows you to specify:

    • The id of the object
    • The class to be applied. Several can be specified, space-delimited.
    • An object array containing in-line styles to apply.

    The id of the object is typically defined as the window to which this element belongs, plus '_', plus the variable name.

    • <window>_<varName>

    Example:

    • winMine_txtBlah

    Iterating fields (for example in a table) would be ID'd with the iteration number:

    • <window>_<varName><iterationVariable>

    Example:

    • winMine_lblBlah1
    • winMine_lblBlah2

    For example:

    var vars={};
    vars.winSelf=Ti.App.createWindow('winSelf','anyWindow',{});
    vars.vwSelf=Ti.App.createView('winSelf_vwSelf',,{});
    vars.winSelf.add(vars.vwSelf);
    vars.vwSelf.add(Ti.App.createLabel('winSelf_lblText','generalLabel',{
        text : "Enter Text",
        top : "50%",
        left : "1%",
        width : "48%"
    }));
    vars.txtText=Ti.App.createLabel('winSelf_txtText','generalText',{
        top : "50%",
        left : "51%",
        width : "48%"
    }));
    vars.vwSelf.add(vars.txtText);
    vars.winSelf.open();
    
    • This example shows a variety of creation and opening mechanisms.
    • It also shows a variety of styles applied, from Class, ID and in-line.
    • Typically, a variable does not need to be created separately if it is never referenced again - see the creation of the label above.
    • The example also shows the use of the vars variable, typically used to make disposing of objects quicker on closing of a window (see Garbage Collection)

    Hierarchy of Classes

    • Class (last takes precedence over first)
    • Device-Specific Class (Hi-resolution, Orientation - last takes precedence over first)
    • Style-specific Class (last takes precedence over first)
    • Style-specific Device-Specific Class (Hi-resolution, Orientation - last takes precedence over first)
    • ID
    • Device-Specific ID (Hi-resolution, Orientation)
    • Style-specific ID
    • Style-specific Device-Specific ID (Hi-resolution, Orientation)
    • In-line properties (highest precedence)

    Custom Controls

    Custom controls have been created as part of the style object, in order to simplify the creation of a complex series of options, or to create an object that Titanium doesn't provide.

    • Custom Tab - used when a tab object is required within a window, rather that outside, like TabGroup.
    • Checkbox - a standard check-box, that changes from a cross to a tick, and vice versa.
    • UDF - User-defined field object. This is a object of many fields, defined by an XML configuration, e.g. Vehicle Checks.
    • Warning Warning: customTab and how to use it.
    • Warning Warning: Vehicle checks - UDF configurable fields and how to use them.
    • Warning Warning: Scrolling views and why they're better and worse than a table.

    Source Control

    When checking in items, use the Team Synchronisation view of Titanium so you can see all changes you have made from the baseline.

    Click Synchronise when using for the first time - always synchronise changes before a build.

    The legend on the file-list should indicate whether:

    • The local file is changed and needs committing.
    • The SVN file has changes in that you need to incorporate into your local files.
    • Conflicting changes (both of the above).

    In all cases, this view can be used to see the changes and incorporate changes into your local file until the changes have been merged - simply double-click on the file to be shown a list of all changes. Use the buttons provided to search for, incorporate or ignore changes.

    The following standard rules apply to Android work:

    • Assign the development to yourself (either through the standard Supimix procedures or from the Log List)
    • Check out the source code through the Source Control software or direct from the Studio software.
    • Make any changes and test locally.
    • When complete, check in your changes with an appropriate comment, initially referencing the log. For example:
      • 291925 - Fixed X when Y happens
    • Update the log to Development Complete status in Supimix (or Fixed status on a log list), ensuring that you enter resolution notes.
    • Assign the log to a tester, who will then test the functionality and close the log (or reassign to be released in a patch).

    Commenting Code

    Code is automatically documented through JSDoc, so valid commenting of code (functions, classes, properties, methods and files themselves) is important.

    • Comment with /** ... */ BEFORE the declaration of the item you wish to comment.
    • Multi-line comments should always be preceded with an asterisk on each line, as in the examples below.

    Files should have a comment on the top as follows:

    /**
     * @file Description of the file
     * @namespace ANameForTheFile
     * @version 1.0
     */
    

    Functions and definitions that are not part of a class should be commented as follows:

    /** 
     * This function does blah.
     * Links to external sites (like the documentation) can be done like this {@link http://172.198.45.54/calidus-assist/EPOD/index.php/PDA_Job_Details}. 
     * html can be inserted to make the comments look better in the generated documentation, as follows:
     * <ul>
     * <li>Address & Contact</li>
     * <li>Instructions</li>
     * </ul>
     * @param {function} funJDCallback Each parameter will be documented like this. Put square brackets around them to indicate optional.
     * @param {PDA_JOB} PDAJOB Links to other parts of the documentation can be made with the the link command, as follows: {@link Database.PDA_JOB} 
     * @returns {Ti.UI.window} The window object to be displayed.
     * @memberof ANameForThisFile
     */
    

    Class definitions/prototypes should have the main function commented as follows:

    /**
     * This object is declared and instantiated in this file.
     * 
     * @memberof ANameForThisFile
     * @constructor
     **/
    

    Class methods and properties should be commented as follows:

    /**
     * This method does as follows
     **/
    

    Notes:

    • @memberof must reference an actual namespace that has already been declared, but not necessarily within this file. So, a namespace declared in file1 as UI can be referenced in file 2. Indeed, the file itself can be made a member of another namespace, to group lots of other namespaces together. So, for example, app.js is named UI, Login.js is named Login, but is a member of UI.
    • Properties and methods of a class do not need to be declared as a memberof something, as they are automatically part of the constructor class.
    • All other commented functions in Namespaced files must be a member of a namespace, or they will be listed as Global functions in the documentation.
    • Properties or methods of a class can be linked to with {@link namespace.class#property}
    • Functions or variables in a namespace must be linked as follows: {@link namespace.function}
    • @version should only be used on files. It should be version 0.1 while being written, then 1.0 when finished. The version only needs to be changed if there are major changes to the document.
    • For EPOD application specifics:
      • DAL objects should be a member of the Database namespace
      • New screens should be a member of the UI namespace
      • New connection-based files (i.e. webservices) should be a member of the Webservices namespace.

    Developer Debugging

    Warning Warning:

    • Running it through the emulator
    • Debug mode and how it works
    • SQLite3
      • Root only
      • How it can be accessed
      • What you can do in it
    • DDMS and what it can do for you.

    Other

    This section details observations, suggestions and potential pitfalls that may aid the Titanium developer.

    Warning Warning: entire section needs expanding.

    • Include files once - describe why
    • Describe synchronous and asynchronous parts of the code, and why return and callbacks are your friends.
    • When debugging on emulator and you want to pick up latest changes, you could click the run button again in Titanium. Faster can be clicking on the app within the emulator - it will reload almost every change (that has been saved). Sometimes it fails though.
    • above, when running again from titanium, get lots of errors regarding can't build because file is in use. You can try stopping previous background tasks, or you can persevere - usually picks up again after a few goes. Stopping and starting Titanium resolves lots of things...
    • Preference changes and i89n (multilingual) changes do NOT get picked up when restarting the app from the emulator. In fact, sometimes you may need to force this by cleaning the project and rebuilding, then installing from Titanium again.
    • adb can time-out if left for a while. If you start the app on the emulator and it hangs, that's probably what happened. Start the app from Titanium. If that doesn't work, reset adb from DDMS. If that doesn't work, exit the emulator, the start the app from titanium - should load another emulator. If that doesn't work, restart your PC.
    • Close and null DB and RS objects after use, or you get runtime errors.
    • Warning Warning: add others here.