Currently Being Moderated

I recently attended my first Appcelerator conference in Melbourne Australia (Presentations can be found here http://eventifier.co/event/tiConfAU13/ ) which covered developing mobile applications with the Titanium SDK. The conference was very impressive with the CEO Jeff Haynie kicking off the keynote speech, which was followed by some quality presentations covering various aspects of mobile development with the Titanium SDK.

 

The Titanium SDK allows developers to code in JavaScript and create native applications for the following platforms  -

  • iOS
  • Android
  • Blackberry 10
  • Tizen
  • Mobile Web

 

Windows 8* support is planned later this year.

 

Appcelerator also provide a free Eclipse based IDE, Titanium Studio as well as a Command-Line Tool for creating Titanium applications.

 

As a newbie to the Appcelerator community there were a number of things that impressed me during the conference -


  • Vibrant community with over 500,000 developers who have built over 60,000 apps that have been deployed to over 160 million devices. The community have also contributed over 12,000 bug fixes to the SDK which is open source on Github -> http://github.com/appcelerator
  • Ability target the key mobile platforms with native apps & mobile web; all using JavaScript
  • Strong/exciting roadmap for Titanium SDK / Appcelerator Cloud Services as outlined in Jeff’s Keynote, especially TiNext (Appcelerator was recently rated the most visionary MADP by Gartner) Additional information about the TiNext release can be found on Jeff's blog -> TiNext

 

Alloy MVC Framework


One of the key takeaways from all the presenters was to make sure you use the Alloy Framework when building your Titanium applications. Alloy is a MVC framework that aims to improve the quality and consistency of Titanium applications and includes built in support for Backbone.js and Underscore.js. The Alloy framework also promotes code reuse via modules/widgets. Examples of these modules can be found at http://alloylove.com, many of which have been built by the community. In the example application we'll use a simple widget for a loading dialog.  An overview of Alloy and its concepts can be found here Alloy Framework

 

So to get my feet week with the Titanium SDK I’ve created a basic Alloy application that calls the NetWeaver Gateway Demo system to display some Business Partners.

 

Prerequisites

  • Titanium Development environment is installed and configured. The installation / quick start guide can be found here - Quick Start

 

  • You have access to the demo gateway services. You can sign up to the services following the guide(s)

http://scn.sap.com/docs/DOC-40986

http://scn.sap.com/docs/DOC-31221

 

 

1. Create Alloy Project

 

Launch Titanium Studio and create a new Alloy Project with the default project template. Click next and then define the project name, App Id and target platforms.

 

CreateAlloyProject.png

 

After clicking finish the project is created with the following structure -

AlloyStructure.png

 

Folder / FileDescription / Purpose
AssetsContains folders for each platform. When building each target application, Titanium has the smarts to only package the resources required for each platform
ControllersEach controller is defined in this folder, which is responsible for reacting to user events as well as interacting with the models of the application
ModelsContains your model objects
StylesContains the .tss files that set the style of the application. tss files are similar to CSS but are more flexible and contain some Titanium specific values
ViewsThis is where you define the presentation layer of your application using XML. The available xml elements are match the UI elements defined in the Titanium SDK; refer to the online documentation for the complete list
alloy.jsThe file is called when the application is launched. It generally is used to perform any application initialization and set functions and variables that are globally accessible throughout your Alloy application
config.jsonDefine configuration parameters for the application such as environment and widget dependencies


 

2. Load the Business Partner Data

 

When the application is launched it needs to call the Gateway service to retrieve the business partner details. In the alloy.js file we'll call the service and store them in the Alloys.Globals.data object to be accessed later in the application.

 

Business Partner Service -

https://sapes1.sapdevcenter.com/sap/opu/odata/IWBEP/GWDEMO/BusinessPartnerCollection?$format=json


alloy.js -

 

//Get the Business Partner List
function getBusinessPartnerList() {
 // Create HTTPClient for calling the Gateway Service
 var sendit=Ti.Network.createHTTPClient({
                              onerror: function(e) {
                                        Ti.API.debug(e.error);
                              },timeout:10000,
          });
 // Will need to add your username/password
 var username='XXXXXXX';
 var password='XXXXXXX';
 // Call NetWeaver Gateway Demo System to retrieve list of business partners
 sendit.open('GET','https://sapes1.sapdevcenter.com/sap/opu/odata/IWBEP/GWDEMO/BusinessPartnerCollection?$format=json&$top=5');
          sendit.setRequestHeader('Authorization','Basic '+Ti.Utils.base64encode(username+':'+password));
          sendit.send();
 // Function to be called upon a successful response
 sendit.onload= function() {
                    var json = JSON.parse(this.responseText);
                    json = json.d.results;
                   var bpData = [];
  // Populate the Business Partners Array and store the result in Alloy Globals
  for (var i = 0, len = json.length; i < len; i++) {
                        var result = json[i];
                        bpData.push({ bp: result.BusinessPartnerID, company: result.Company, role: result.BusinessPartnerRoleText, email: result.EmailAddress, webaddress: result.WebAddress, phone: result.TelephoneNumber, hasChild:true });
                    }
                    Alloy.Globals.data = bpData
          };
};


3. Display the Business Partner List

 

The index.xml view will display the list of business partners returned from the Gateway Service. We need to create a second view&controller called “row” that will contain each row representing a BP in the index views MasterTable.


A cool feature with Alloy is the platform attribute against the UI elements. This give you the ability to create specific layouts for different operating systems. E.g. in the index view below the master table is embedded within a Navigation Group for iOS and MobileWeb while for android a HeaderView element has been embedded in the master table

IndexView.png

 

The index.js controller loops through the BP data stored in Alloy.Globals.data and creates and instance of a row for each BP. This array is then set as the data source for the MasterTable in the index.xml view. The Loading widget is also hidden.


// Open the Index View and show the Loading Widget
$.index.open();
$.loading.show('Loading Business Partners', false);
// Add an Event Listener for the BP Data Load Event
Ti.App.addEventListener('BpDataLoaded', function(e){
 // Loop through the BP Data using the underscore.js "each" function 
 // and create a new row controller&view 
 _.each(Alloy.Globals.data, function(bp) {
          data.push(Alloy.createController('row', {
                    bp: bp.bp,
                    company: bp.company
          }).getView());
          });
 // Hide the Loading widget after creating the table rows
 $.loading.hide();
 $.MasterTable.setData(data);
 
});

 

To use the Loading widget which I got via AlloyLove.com ( https://github.com/FokkeZB/nl.fokkezb.loading thanks Fokke ZB) you need to create a widgets folder and copy the downloaded widget into that location. Too easy

 

Loading.png

 

Then update config.json with the dependency and then the widget is available throughout your application

 

config.png

 

 

4. Display the Business Partners Details

 

The DetailView is a simple view that shows BP details and allows the user to perform some basic actions e.g. click to call/ launch website / email contact. This logic is located in the detail.js controller.

 

detail.xml

<Alloy>
 <Window class="container" layout="vertical">
  <Label id="name" platform="android"/>
  <Label id="bp"/>
  <Label id="role"/>
  <Label id="webaddress" onClick="handleDetailClick"/>
  <Label id="phone"  onClick="handleDetailClick"/>
  <Label id="email"  onClick="handleDetailClick"/>
 </Window>
</Alloy>

 

When the user clicks on a row in the index.xml view, the index.js controller calls the "setBpDetail" function in the detail.js controller, setting the applicable text value for each label in the detail.xml view

 

exports.setBpDetail = function(bp) {
 // Use the underscore.js "find" function to retrieve the Business Parter record using the BP ID
 var bpData = _.find(Alloy.Globals.data, function(bpData) {
                    return bpData.bp == bp;
          });
 // Set the applicable label text properties with the BP Details
 if (OS_ANDROID) {
                    $.name.text = 'BP: ' + bpData.company;
          } else {
                    $.detail.title = bpData.company;
          }
          $.bp.text = 'No: ' + bpData.bp;
          $.role.text = 'Role: ' + bpData.role;
          $.webaddress.text = 'Website: ' + bpData.webaddress;
          $.phone.text = 'Phone: ' + bpData.phone;
          $.email.text = 'Email: ' + bpData.email;
};

 

To handle the call/email/website actions, the detail.js also has a function called "handleDetailClick"

 

// Handle Click Events on Detail Page
function handleDetailClick(e) {
          var value = arguments[0].source.text.substring((arguments[0].source.text.indexOf(" ")+1));
 // Depending on which label was clicked execute the appropriate action
 switch(arguments[0].source.id){
  case 'phone':
  // Dial the phone no. with the native dialer
  Titanium.Platform.openURL('tel:' + value);
  break;
  case 'webaddress':
  // Launch the BP's website in the phone's browser
  Titanium.Platform.openURL(value);
  break;
  case 'email'
  // Launch the Email Dialog, pre-populating the fields 
  var emailDialog = Titanium.UI.createEmailDialog();
      
    emailDialog.setSubject('TiAlloy Gateway!');
                        emailDialog.setToRecipients([value]);
                        if (OS_IOS) {
                            emailDialog.setMessageBody('<b>Hello TiAlloy Gateway!</b>');
                            emailDialog.setHtml(true);
                            emailDialog.setBarColor('#336699');
                        } else {
                            emailDialog.setMessageBody('Hello TiAlloy Gateway!');
                        }
                        emailDialog.open();
                        break; 
          }
}

 

Source Code / Demo Videos

The full source code can be downloaded from the Github repository here - https://github.com/stephenkringas/TiAlloyGateway

 

Videos of the app running on the simulators -


iPhone

 

Android

 

 

 

Main Hurdles


 

Environment Setup

When building this application the biggest pain point was just getting the environment setup. On my Windows desktop I had issues getting the IDE recognize my Android SDK. After trying to fix the issue following a number of forum posts and JIRA ticket workarounds I ended up just using my MacBook, which I configured on the first attempt.

My understanding is moving forward, Appcelerator is going to be focusing more on the Command-Line tool instead of the Eclipse IDE because of such issues.

 

Debugging / Troubleshooting

 

Another aspect that took a bit of getting used to was debugging/troubleshooting the application. Titanium Studio provides a debugger but with my lack of familiarity with the framework it took some time to pinpoint where the issues were.

 

A useful tip was using the Ti.API.debug() function which gives you the ability to view trace messages in your console when running the app. To view the debug messages you need to update the Log Level in the Run configuration to “Debug” -

 

Debug.png                   

 

 

 

Titanium Learning Resources

 

If you’re keen to dig into Appcelerator/Titanium,  a good starting point are the following resources

 

 

SK

Comments

Actions

Filter Blog

By author:
By date:
By tag:

Incoming Links