Titanium Community Questions & Answer Archive

We felt that 6+ years of knowledge should not die so this is the Titanium Community Questions & Answer Archive

Tips and tricks (mobile) - thread to share some experience that may help the others

I would like this to be a thread to make a sum of tips and tricks or share our experience to help other coders.

So I'll start with what I found until now :)

  1. Remember that the device is not as speedy as the simulator.

  2. When you need to use a webView, try to communicate with the app as less as possible.
    If you need to create new elements in the interface, do it before you launch the webView and not while the webView is active, and attach it to the window from the webView. If you need to make calculations ( for example to catch the touchmove coordinates) inside webView, do it in the javascript from inside he webView, and send the result to the app at the end ( on touchend maybe ).

  3. If you have to store persistent data, but is not an sql data ( for example you need to remember some settings the user is able to configure ) use Titanium.App.Properties and not Titanium.Database.

  4. Test your application on the device( if possible ). You will find that you might need to improve the usability - for example you might ned to add a "Loading…" view to mask a slow loading component, and provide in the same time feedback to the user. ( this is somehow related to the point 1. )

I'll try to update the list, but I hope others from the list will participate too :)

— asked March 22nd 2010 by Dan Tamas
  • mobile
  • tips
3 Comments
  • Beginnings of a collection of Javascript debug helpers:

    http://appcelerated.wikispot.org/Debugging

    — commented August 30th 2010 by Alan Bourke
  • I created these SearchPlugins for your browser (compatible with Firefox, Chrome, IE7 & IE8) that I use all the time.

    — commented November 7th 2010 by Paul Dowsett
  • "Remember that the device is not as speedy as the simulator"

    For iPhone, it may well be. For Android, unless you have an absolute monster of a PC and a really bad device, the device will be far faster in terms of starting up and re-deploying builds.

    — commented March 23rd 2011 by Alan Bourke

78 Answers

  • It takes minimal extra effort to target the Android platform as well as the iPhone. Take a bit of extra time to make sure your app works on both (using platform detection where you need to do something slightly differently, or need to skip a function that causes the app to crash on one device).

    if (Titanium.Platform.name == 'android') {
        // Android stuff
    }
    

    Connect to test data-sources by detecting whether the app is running in a simulator.

    if (Titanium.Platform.model == 'google_sdk' || Titanium.Platform.model == 'Simulator') {
        // Simulator variables
    }
    
    — answered August 11th 2010 by Matt Collinge
    permalink
    1 Comment
    • Calling Titanium.Platform.* causes a call across the device API that is slower than having a variable that is set at application start.

      Try using:

      var android = (Ti.Platform.name == 'android') ? true : false;
      

      and then later:

      if (android) }
          // Android stuff
      }
      

      — commented August 8th 2013 by Richard Gaushell
  • Use my brother's Titanium Redux (you just include one javascript file into your context) to help clean up your code. The most important thing it gives you is JSS (similar to CSS) for reusable styles on your controls. You can specify styles based on control type, control id, or class name.

    https://github.com/dawsontoth/Appcelerator-Titanium-Redux

    — answered November 15th 2010 by Justin Toth
    permalink
    4 Comments
    • Upvote from me. /love/ this…

      — commented November 15th 2010 by Critter
    • It makes Titanium *ucking awesome. Great!

      — commented September 12th 2011 by Sangcheol Park
    • Cool! I love using it.

      — commented October 20th 2011 by Raghu Kumar
    • this is awesome

      — commented December 5th 2011 by Sahil Grover
  • Hidden functionality of Titanium.Platform.openUrl(); you might not know of!

    Examples

    Calling Phonenumber ( on iPhone does not accept white spaces!! )

    // phoneNumber is a var containing a phoneNumber
    Ti.Platform.openUrl('tel:'+phoneNumber);
    

    Calling Skype! ( not tested on Android )

    // skypeName is a var containing a skypename
    Ti.Platform.openUrl('skype:'+skypeName);
    

    Sending an SMS

    // where smsNumber is a telephoneNumber
    Ti.Platform.openUrl('sms:'+smsNumber);
    

    Opening google maps with a valid address ( not tested on Android )

    // where address is a string containing a street name, city name, zipcode and country name.
    // you don't need them all, you'll figure out what you need as a minimum
    
    // encodeURIComonent is a javascript function that escapes special chars and stuff. Quick solution i used atm
    Ti.Platform.openUrl('http://maps.google.com/maps?q=+encodeURIComonent(address));
    
    — answered May 6th 2011 by Kami -
    permalink
    3 Comments
    • Google Maps URL contains two typos, should be

      Ti.Platform.openUrl('http://maps.google.com/maps?q='+encodeURIComponent(address));
      

      — commented June 16th 2011 by Julien Nebbout
    • works on android, will give you the option to open it in the browser or in the map application

      — commented December 28th 2011 by Blueshift Local
    • operUrl is wrong method…correct method is openURL

      — commented February 25th 2014 by Rama krishna
    1. Titanium HTTPClient runs in a separate thread and often (always?) doesnt release it. Use global client to download multiple files to minimize number of threads. You can make a recursive procedure, that gets called from onreadystatechange or onload (if it fires)

    2. HTTPClient.onload often doesnt fire, use onreadystatechange with readyState == 4

    3. Titanium HTTPClient doesnt close itself automatically, so before reopening it with a different direction, use "abort", or it will bring you the same file as before.

    4. So if u create a client, all your subsequent events and timers will fire in several threads. Titanium threads seem to share variables, so if your event is sensitive to doubled execution, use a simple integer or boolean to create a semaphore.

    — answered August 22nd 2010 by Ganna Kozynenko
    permalink
    3 Comments
    • These sound like very good tips. Does anyone have examples on how to implement them?

      — commented March 17th 2011 by Joe iEntry
    • Same question. I'm writing a multiple download script that is using both HTTPClient and .onload – as suggested in the kitchen sink. Can anyone help expound on this?

      — commented May 19th 2011 by Mike Burk
    • I am currently experiencing the very same problems as outlined above. Would be fantastic to see some implementing code on this matter. Thanks for sharing Anna!

      — commented May 22nd 2011 by James -
  • Here's a few things I've learned along the way:

    1. Comment the top of the JS file with: the name of the file, it's purpose; and any external dependencies the context will use (i.e. properties/window variables) - very useful if reusing the window from multiple directions/paths.

    2. I Ti.API.info the name of the JS file at the start, so I can capture the sequence of navigation when testing. Also useful if you could have obsolete files to check they are not used.

    3. Properties are persistent so you may want to 'remove' them in your app.js - to start afresh

    4. If your window contains data that may get updated, consider putting the display construction code into a discreet function and call it from the window focus event.

    5. use variables attached to rows to store static data about an item, it's easier than locating label object values (and more consistent).

    6. If you have textfields, workout where the keyboard will rise up to and try to avoid obscuring other controls - my current headache!

    — answered August 17th 2010 by Chris Reed
    permalink
    0 Comments
  • Always be sure to show loading screens where applicable. To match Apple's standard loading screen (position, color, etc) I use the following:

    var loadView = Ti.UI.createView({
        backgroundColor: '#d8d8d8',
        height: 480,
        width: 320
    });
    var loadingScreen = Titanium.UI.createActivityIndicator({
        height:50,
        width:210,
        color:'#404347',
        font:{fontFamily:'Helvetica Neue', fontSize:14,fontWeight:'normal'},
        message:'Loading...',
        style:Titanium.UI.iPhone.ActivityIndicatorStyle.DARK
    });
    
    — answered August 18th 2010 by John Welch
    permalink
    2 Comments
    • this doesn't look like standard.

      — commented August 18th 2010 by Caio Iglesias
    • It matches the Apple's AppStore to my knowledge…. Unless I mistakenly changed the background color. Where do you see a difference?

      — commented August 19th 2010 by John Welch
  • For quick tracing of info.. I have a function I call…

    function trace(msg)
    {
       Ti.API.info(msg);
       Ti.API.info("Available memory: " + Ti.Platform.availableMemory);
    }
    
    — answered October 5th 2010 by Critter
    permalink
    2 Comments
    • Easier way…

      var info = Ti.API.info;
      info("log me!");

      — commented November 20th 2010 by Justin Toth
    • Maybe use this one:

      function log(str) {
      Titanium.API.info((typeof str == "object") ? JSON.stringify(str) : str);
      }

      — commented February 2nd 2012 by Rafael Cardoso
  • I made a small tutorial on how to create custom rows in tableView.

    http://cssgallery.info/custom-row-for-tableview-in-appcelerator-titanium/

    I hope it will be useful.

    — answered April 16th 2010 by Dan Tamas
    permalink
    2 Comments
    • Excelent tutorial, well done. ;]

      — commented June 6th 2012 by José Júnior
    • awesome tutorial …Thanks for sharing.

      — commented October 16th 2013 by Anu Sharma
  • ###Increase Application Speed by 50-75%

    If you use tables in your application and add more rows on a click event or such, these two tips can increase the speed of your app by 50-75%!

    ####ALWAYS group similar rows with className

    Using a className was the first step I took to optimize performance of my application and I noticed about a 50% speed increase over not using a className.

    "Rendering rows is an expensive operation, particularly when their layouts are complex. By setting the className property with a common value for each row layout, you enable the platform to make its calculations once and reuse them for the other, similar rows. Although it is not recommended for Simple TableViews, you should use this property every time you utilize a Standard TableView." (Source: wiki.appcelerator.org)

    ####Use Simple TableViews

    Using simple TableViews I noticed nearly a 75% speed increase in load time compared to using a standard TableView. Thus, I had to eliminate the use of images and labels, but the speed benefit is worth the cost of not as good of looks.

    "There are many more calculations involved for your mobile platform to produce a Standard TableView compared with a Simple TableView. Hence, don't use the former when the latter will suffice." (Source: wiki.appcelerator.org)

    — answered March 17th 2011 by Joe iEntry
    permalink
    5 Comments
    • Thanks! I didn't know about 'simple' vs. 'standard' table views.

      — commented March 18th 2011 by Robb Shecter
    • Oh, but hold on … I don't see this distinction doc'd anywhere else. :-( E.g., "simple" is used in quotes, but is it actually a keyword or API method?

      — commented March 18th 2011 by Robb Shecter
    • In other words, just provide a title property in a JavaScript object literal vs constructing your own TableViewRow with multiple view elements in each row. The advantage is efficiency. The disadvantage is you can only have one text element and an icon in the each row.

      var data = [{title:"Row 1"},{title:"Row 2"}];
      var table = Titanium.UI.createTableView({data:data});
      

      — commented June 11th 2011 by Jason Harrelson
    • I recently had terrible issues with some complex TableViews - basically crashing on setData almost every time it was called for a 'refresh' following the initial setData. Tore my hair out trying to fix it - but ended up rewriting the code to use Views inside a ScrollView (layout:vertical). Worked a treat! Faster, stable and more flexible.

      Bottom line AVOID tableViews like the plague unless you really, really need to use them!

      — commented March 13th 2012 by Chris King
    • Chris King. Thank you!!! I've been struggling for weeks now getting an app to be compatible on Android (it works flawlessly on iOS, of course) and doing what you suggested solved all my tableView woes. These Titanium tableViews are sure not Android friendly.

      — commented July 30th 2012 by Donald Hruska
  • I have a new tutorial on how to create a tooltip.

    http://cssgallery.info/create-a-nifty-tooltip-in-titanium/

    — answered April 19th 2010 by Dan Tamas
    permalink
    0 Comments
  • I was having troubles getting any sort of GPS data in the android emulator. Even the built-in maps app wouldn't show a location. I found a way to set mock coordinates that solved my issue. I'm working on Windows, sorry Mac users you'll have to interpret/adjust.

    First, open ddms (Dalvik Debug Monitor). On Windows, navigate to the android-sdk\tools directory and run ddms.bat. The first line in the top-left pane will read something like "emulator-####" such as emulator-5560.

    Open a command prompt window. Enter 'telnet localhost ####' substituting the number you found above. This will open a telnet window to your android emulator.

    Enter the following command (substitute your own longitude & latitude, in that order, if you'd like):

    geo fix -82.411629 28.054553
    

    (I'm pretty sure you can add elevation as a third number.) The GPS icon will appear in the emulator's notification bar. Geolocation is now available. At this point, I could get location data in my app and in other apps, such as Maps.

    You don't have to leave the telnet session running. Closing it doesn't turn off the GPS.

    I hope this helps. Tim

    — answered August 24th 2010 by Tim Poulsen
    permalink
    1 Comment
    • Thanks very much Tim for this help. I wan't to know please, when the users of my mobile app are connected how their GPS coords will be detected automatically ? how can i let my app detect their current position ?
      I'm begineer on titanium developpemnt that's why i wan't to have a clear idea about this. Thanks a lot.

      — commented August 17th 2014 by MAY sameh
  • Hi guys, I just launched Adamantium.js – chainable mobile app framework with jQuery-like syntax, based on TiFramework by Rick Blalock. Basically, it's a framework that let's you write code more or less like you would when developing websites and webapps with jQuery. It's open source and you can read the original blog post, browse examples and docs and download the example app. There's also a separate Q&A thread for feedback.

    Create the main screen with child elements and event handlers.

    SCR.MyScreen = $('Screen')
        .attr('title', 'My first screen')
        .add('UI.View', {
            id: 'MyScreen.View',
            height: 100,
            width: 100,
            backgroundColor: '#fc3',
            top: 100
        })
        .bind('click', function (e) {
            alert(e.source.id + ' was clicked!');
        })
    ;
    

    Use object reference as selector for components and ID as string when selecting elements. The type selector lets you select multiple components or elements with one query.

    $(SCR.MyScreen) // object
    $('#MyScreen.View') // ID
    $(':View') // type
    

    There's plenty more examples in the original blog post and the example app, so check them out!

    — answered April 25th 2011 by Adam Renklint
    permalink
    0 Comments
  • I have implemented Timer which works for IOS and android. It has start,stop,reset,pause and resume funtions. I hope it will help others .

    var win = Ti.UI.currheUI.createLabel({
        text : '00:00',
        font : {
            fontSize : 35
        },
        top : 30
    })
    win.add(TimerLabel);
    
    var Clock = {
        totalSeconds : 0,
        start : function() {
    
            var self = this;
    
            this.interval = setInterval(function() {
                self.totalSeconds += 1;
    
                var hours = Math.floor(self.totalSeconds / 3600);
                var min = Math.floor(self.totalSeconds / 60 % 60);
                var sec = parseInt(self.totalSeconds % 60);
                TimerLabel.text = '' + hours + ':' + min + ':' + sec;
            }, 1000);
        },
    
        pause : function() {
    
            clearInterval(this.interval);
            delete this.interval;
    
        },
    
        resume : function() {
            if (!this.interval)
                this.start();
        },
        stop : function() {
            clearInterval(this.interval);
        },
        reset : function() {
            clearInterval(this.interval);
            this.totalSeconds = 0;
            TimerLabel.text = '0:0:0';
    
        }
    };
    
    var startBtn = Ti.UI.createButton({
        title : 'Start',
        top : 70,
        left : 10
    });
    var stoptBtn = Ti.UI.createButton({
        title : 'Stop',
        top : 70,
        right : 10
    });
    var pauseBtn = Ti.UI.createButton({
        title : 'Pause',
        top : 150,
        left : 10
    });
    var resumeBtn = Ti.UI.createButton({
        title : 'Resume',
        top : 150,
        right : 10
    });
    var resetBtn = Ti.UI.createButton({
        title : 'ReSet',
        top : 200
    });
    win.add(startBtn);
    win.add(stoptBtn);
    win.add(pauseBtn);
    win.add(resumeBtn);
    win.add(resetBtn);
    
    startBtn.addEventListener('click', function(e) {
        Clock.start();
    });
    stoptBtn.addEventListener('click', function(e) {
        Clock.stop();
    });
    pauseBtn.addEventListener('click', function(e) {
        Clock.pause();
    });
    
    resumeBtn.addEventListener('click', function(e) {
        Clock.resume();
    });
    
    resetBtn.addEventListener('click', function(e) {
        Clock.reset();
    });
    
    — answered November 2nd 2013 by Muhammad Adnan
    permalink
    0 Comments
  • For complex table layouts you can improve performance by adding labels etc to a view, then adding that view to a row. Adding the labels directly to the row doesn't seem to perform as well.

    — answered August 11th 2010 by Matt Collinge
    permalink
    1 Comment
    • Brilliant concept! I am struggling to try to improve the performance of adding my rows, and I can see where this could be much more efficient. But I can't get the syntax worked out – at least for Android. I keep getting null object references.

      I am assuming here that the creation of the view with the labels (etc) happens just once, prior to loop iteration populating the rows. Then by just adding that pre-defined view, all the controls for the row are defined in one fell swoop, saving the time to parse the calls and create the objects.

      Let's say each row will have 3 labels, myLabel1, myLabel2, and myLabel3. If we create a view called myView and add the 3 labels to it while populating the table we get something like:

      var myRow = Ti.UI.createTableViewRow( … );
      myRow.add( myView );

      but now how do we set the text of the labels? Variations of this don't seem to work:

      myRow.myView.myLabel1.text = "Some text";
      myRow.myView.myLabel2.text = "Other text";
      myRow.myView.myLabel3.text = "foo bar";

      At least under Android and using the 1.4 SDK, I can't find a syntax that works. I also tried JSON.stringify() and dumpObj2() in an effort to find the object/property names to use.

      I also tried variations trying to update the label text in myView prior adding the view to myRow which cuts out one object level. But I couldn't get to work either.

      Can you post some pseudo code please?

      — commented October 23rd 2010 by Doug Handy
  • Tableview click event.

    Always assign var to tableview click event to prevent multiple events registered and executed when refresh or reload on the same table lists.

    If you fresh tableview with this, or has a common function on different tabs loading diff. tableviews, tableview click event will trigger multiple times using this

    tableview.addEventListener('click',function(e){
    Ti.API.info('table view click')
    })
    
    or
    
    table_event = tableview.addEventListener('click',function(e){
    Ti.API.info('table view click')
    })
    

    you must use this to prevent duplication

    var table_event = tableview.addEventListener('click',function(e){
    Ti.API.info('table view click')
    })
    

    and probably a good practice to do the same for other event handlers

    — answered August 11th 2010 by Daniel Lim
    permalink
    3 Comments
    • Nice tip. Could this be a bug in Titanium? Or should it work like this?

      — commented August 20th 2010 by Matt Collinge
    • Does anyone have more information on this? If I had three different events for the same tableview would they all have the same var table_event or individual vars? Is there a document somewhere that talks about variable scope, particularly when dealing with tabgroups? For example if I have four different tabs (windows defined with url .js files) can i use the same variable names in each window or do they need to all be unique through the program?

      Thanks!

      — commented October 25th 2010 by Chris Campbell
    • This is definitely a bug.

      — commented November 27th 2010 by Ernesto Mendoza
  • Written a small snippet to extract / parse and deploy KML data on a maps via javascript

    here is the link

    inline

    — answered August 18th 2010 by j J
    permalink
    0 Comments
  • Beginnings of a collection of Javascript debug helpers:

    http://appcelerated.wikispot.org/Debugging

    — answered August 30th 2010 by Alan Bourke
    permalink
    0 Comments
  • Here is my code to create a collapse/expand view. I was struggling on how to create the animation but got the solution from Liping Zong post. http://developer.appcelerator.com/question/75261/animation-while-incrementing-height-of-textarea#your-answer

    Here is my solution. Will try and make it more generic and post in GIT soon.

    var win = Titanium.UI.createWindow({backgroundColor:'#FFFFFF'});
    
    var view = Ti.UI.createView({
        backgroundColor:'#EAE6DB',
        layout:'vertical',
        top:10,
        left:10,
        height:150,
        right:10,
        borderRadius:10,
        zIndex:0
    });
    
    var hideShowButton = Ti.UI.createButton({
        backgroundImage:'arrow_contract.png',
        top:5,
        right:5
    });
    
    var separator = Ti.UI.createView({
        top:10,
        right:0,
        left:0,
        height:25,
        backgroundColor:'#B97A57',
        zIndex:1
    });
    
    var showHideButtonClicked = true;
    
    hideShowButton.addEventListener('click', function() {
        var animHeight = Ti.UI.createAnimation();
    
        if (showHideButtonClicked) {
            animHeight.height = 150;
            animHeight.duration = 500;
            view.animate(animHeight);
            hideShowButton.backgroundImage = 'arrow_contract.png';
            showHideButtonClicked = false;
        } else {
            animHeight.height = 30;
            animHeight.duration = 500;
            view.animate(animHeight);
            hideShowButton.backgroundImage = 'arrow_expand.png';
            showHideButtonClicked = true;
        }
    });
    var label1 = Ti.UI.createLabel({
        left:20,
        text:'Allergen Name',
        color:'#fff'
    });
    
    var label2 = Ti.UI.createLabel({
        left:250,
        text:'Reaction',
        color:'#fff'
    });
    
    var label3 = Ti.UI.createLabel({
        left:450,
        text:'Notes',
        color:'#fff'
    });
    
    separator.add(label1);
    separator.add(label2);
    separator.add(label3);
    
    view.add(hideShowButton);
    view.add(separator);
    
    win.add(view);
    win.open();
    

    Hope this helps

    — answered February 21st 2011 by Samanth Bapu
    permalink
    0 Comments
  • Extend the string class with inflections (a la Ruby). My most useful inflection is String#constantize. You can use this to instantiate classes dynamically based on an interpolated name.

    var $global = this;
    
    String.prototype.constantize = function()
    {
      var constant = $global[this];
    
      if( constant == null ) throw( 'Failed to constantize string:' + this );
    
      return constant;
    };
    

    Usage:

    var OneClass = new HoweverYouDefineYourClasses(
    { 
      ...,
    
      sayHello: function()
      {
        alert( 'Hello from OneClass' );
      }
    });
    var TwoClass = new HoweverYouDefineYourClasses(
    { 
      ...,
    
      sayHello: function()
      {
        alert( 'Hello from TwoClass' );
      } 
    });
    
    var things = ['One', 'Two'];
    
    for( var i=0; i<things.length; i++ )
    {
      var object = new ((things[i] + 'Class').constantize())();
      object.sayHello();
    }
    
    // => Hello from OneClass, Hello from TwoClass
    

    Dynamic programming such as this can really DRY (Don't Repeat Yourself) up your code.

    — answered June 10th 2011 by Jason Harrelson
    permalink
    1 Comment
    • That is a fabulous tip! Thanks!

      — commented May 31st 2012 by Cornell Campbell
  • In 1.0+ you can now use alert() to create a generic pop-up alert msg on the iphone.

    alert('Hello!');
    

    (You no longer need to create a variable like so: var a = Titanium.UI.createAlertDialog(); a.setMessage("asdf");….)

    — answered March 22nd 2010 by Ryan Gartin
    permalink
    2 Comments
    • alert() is not cross-platform compatible. Stick with Titanium.UI.createAlertDialog() method if you plan to develop on something other than iOS.

      — commented September 12th 2011 by Michael Stelly
    • alert() works great on all platforms

      — commented December 15th 2011 by mo joe
  • Adding properties to a View won't work, unless you do it on the constructor.

    • Without initializing the property on the constructor
      ~~~
      var rowCreada = Titanium.UI.createTableViewRow( {

                    className: 'clase1'
                } );
      

      var labelTitulo = Titanium.UI.createLabel( {

            text: 'Titulo',
            color: '#000000',
            textAlign: 'center',
            bottom: 2,
            height: 16
        } );
      

      rowCreada.add( labelTitulo);

      rowCreada.labelTitulo = labelTitulo;

    Ti.API.info( 'label: '+ rowCreada.labelTitulo );  // PRINTS "label: null"
    
    
    - Initializing the property on the constructor
    
    var rowCreada = Titanium.UI.createTableViewRow( {
                    labelTitulo: '',
                    className: 'clase1'
                } );
    
    var labelTitulo = Titanium.UI.createLabel( {
            text: 'Titulo',
            color: '#000000',
            textAlign: 'center',
            bottom: 2,
            height: 16
        } );
    
    rowCreada.add( labelTitulo);
    
    rowCreada.labelTitulo = labelTitulo;
    

    Ti.API.info( 'label: '+ rowCreada.labelTitulo );  // PRINTS "label: ti.modules.titanium.ui.LabelProxy@43f718d"
    

    ~~~

    — answered November 19th 2010 by Mat Lop
    permalink
    0 Comments
  • Hi there,

    If you are ready to deploy to the App Store but realise that the Titanium Project Name isn't what you want displayed as the App Name (which is the standard for iOS from Ti) - here's how to specify a distinct App Name:

    1. Copy info.plist from your build/iPhone folder to the project root.
    2. Edit the string value for <key>CFBundleDisplayName</key> to be the desired title for the app on the device.
    3. delete the files (not subfolders) in the build/iPhone folder
    4. rerun the app in the simulator (forcing a rebuild)
    5. check the (regenerated) info.plist file in 'build/iPhone' contains the updated CFBundleDisplayName key value.

    cheers,
    Chris.

    — answered January 7th 2011 by Chris Reed
    permalink
    1 Comment
    • what about android?

      — commented February 25th 2014 by Rama krishna
  • I've made a squidoo lens of some of my lessons learned, hopefully it saves some others some time.

    http://www.squidoo.com/appcelerator-development

    — answered February 9th 2011 by Frank A
    permalink
    0 Comments
  • Distributing "ad hoc" iOS apps to members of your team or company can be a royal pain:

    • Users have to first send you their udid.
    • They have to import a provision profile into itunes.
    • They have to import the app into itunes.
    • They have to sync itunes with their iOS device.

    There is a lot that can go wrong in that process, especially factoring in the technical levels (or lack there of) of the users testing your app.

    For this reason, it saves a lot of time to use Test Flight, which allows you to setup team members, upload iOS builds, and distribute the builds to their phones.

    Note: Test Flight does not work for Android, however it's easy to distribute apk's anyway so it's not that big of a deal.

    — answered January 23rd 2012 by Justin Toth
    permalink
    0 Comments
  • Add plenty of Ti.API.info statements to your code.. I usually prefix each one with the name of the function so that I can tell where it is.

    Ti.API.info('displayWindow - opening window, title=' + title);
    

    It saves so much time when you're debugging an app.

    — answered August 11th 2010 by Matt Collinge
    permalink
    0 Comments
  • Hi i have created a tutorial on how to perform orientation changes on android.

    Here is the link

    — answered August 11th 2010 by Satta Ravi
    permalink
    1 Comment
    • Blog not found :)

      — commented December 6th 2012 by Abdus Sattar
  • i added two snippets on my blog

    A wrapper class for the app properties
    http://alessioricco.com/blog/2010/07/16/appcelerator-wrapper-class-classes-for-titanium-app-properties/

    and

    how to switch between windows programmatically and with no tabBar
    http://alessioricco.com/blog/2010/07/15/appcelerator-how-to-switch-between-windows-programmatically-and-with-no-tabbar/

    — answered August 24th 2010 by alessio ricco
    permalink
    1 Comment
    • The requested page cannot be accessed because the related configuration data for the page is invalid.

      — commented June 9th 2014 by devyani p
  • iphone

    heres some code which lists files in the data application directory in a table and allows you to delete them if you want.

    var win = Titanium.UI.currentWindow;
    win.showNavBar();
    win.barColor = '#999';
    Titanium.UI.setBackgroundColor('#ffffff');
    
    var dirTest = Titanium.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory);
    var dirList = dirTest.getDirectoryListing();
    
    var tv = Ti.UI.createTableView({
        top:'20',
        left:'0',
        editable:true,
        border:'0',
        separatorStyle:'none'
    });
    
    function setData()
    {
        var data = [];
        for (var i=0;i<dirList.length;i++)
        {
            var row = Ti.UI.createTableViewRow({height:33});
            var l1 = Ti.UI.createLabel({text:dirList[(i)], textAlign:'center', font:{fontSize:16}, color:'#888', left:5});
            row.add(l1);
            data.push(row);
        }
        tv.setData(data);
    }
    //---------------------------------add player
    tv.addEventListener('delete',function(e)
    {
    var dfile1 = Titanium.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory, (dirList[e.index]));
    if (dfile1.exists()) { dfile1.deleteFile(); }
    dirList.splice(e.index,1);
    win.addEventListener('focus', function()
    {
    setData();
    });
    });
    
    win.add(tv);
    
    setData();
    
    — answered September 4th 2010 by Robert Greenock
    permalink
    0 Comments
  • Building Titanium (Mobile) from source:

    1. Download the zip

    2. Open Terminal and locate to wherever the zip is

    3. Execute "scons" (or "scons iphone=1" for iphone only)

    4. (Time passes… Thorin sits down and starts singing about gold)

    5. When done, open "dist" folder (just created) and expand zip there

    6. Open "mobilesdk/osx"

    7. Copy the folder there into "Library/Application Support/Titanium/mobilesdk/osx"

    (Restart Titanium Developer if running)

    cheers,
    Chris

    — answered November 16th 2010 by Chris Reed
    permalink
    0 Comments
    • Table View Custom Rows: they were running fine on the Simulator, but randomly crashed the device (iPhone 3GS). The workaround was to cut some properties:

    Before:

    var label1 = Ti.UI.createLabel({
       font:{fontFamily:'Helvetica Neue',fontSize:14,fontWeight:'bold'},
       text:text,
       textAlign:'left',
       left:10,
       right:label2.width + 10,
       height:22
    });
    
    row.add(label1);
    

    After:

    label = Ti.UI.createLabel({
       font:{fontFamily:'Helvetica Neue',fontSize:14,fontWeight:'bold'},
       text:text
    });
    
    row.add(label);
    
    • Another tip: I was using Titanium.App.Properties to pass data from one window to another (via row.addEventListener). The device performance became sluggish. The workaround was to set window properties.
    — answered January 31st 2011 by Luke Days
    permalink
    1 Comment
    • In terms of the random crashes being solved by cutting some properties, my SWAG is it was caused by the expression:

      right:label2.width+10,

      Sometimes I have had issues that went away when I moved an expression to a temporary variable set ahead of a createXxx method. In those cases I just pre-calculate the expression and name the variable for the property value.

      Usually it works for me to use an expression, and I have not detected a pattern to the failures. But just wanted to give you a heads up that would be the first thing I would try if you have it narrowed down to that section of code.

      — commented January 31st 2011 by Doug Handy
  • I just discovered that the iPhone treats image filenames as case sensitive. The Simulator/Emulator, however, does not. For example, I had an imageview defined in my app with a filename of 'images/cardback.png', but the actual filename was 'images/CardBack.png'. It worked fine that way in the Emulator, but when I installed on my iPhone4, those imageviews were replaced with a faint wave default image. Correcting the case, either in the actual filename, or in the imageview declaration, solved the problem.

    — answered February 23rd 2011 by Ryan Case
    permalink
    0 Comments
  • The Titanium Studio shortcut Ctrl + F11 exectute the last "run command". Usefull, if you want restat your app inside the Simulator/Emulator.

    — answered August 12th 2011 by A S
    permalink
    1 Comment
    • Of course on a MAC it's CMD + F11, with the fn key held depending on keyboard settings

      — commented August 31st 2011 by Kelly Redd
  • After spending a few hours trying to find a bug, I discovered that the iPhone simulator was keeping files from old compilations of my app.
    The solution was to run my app in the iOS simulator, then click on the menu
    iOS Simulator
    the click on
    Reset Content and Settings...

    — answered October 4th 2011 by asdfasdfasdfasdf asdfasdfasdfasdfadsf
    permalink
    1 Comment
    • Or just delete the files from the build and let the Titanium to recreate them? :P

      — commented February 2nd 2012 by Rafael Cardoso
  • Here si another post about how to work outside of current context - with props and includes.

    https://developer.appcelerator.com/question/5561/working-outside-of-current-context—with-props-and-includes

    — answered March 23rd 2010 by Dan Tamas
    permalink
    0 Comments
  • Here's a tutorial about how to use custom TableViewRows and how to get at the values of contained controls within those rows.

    http://appcelerated.wikispot.org/TableViewRows

    — answered August 10th 2010 by Alan Bourke
    permalink
    0 Comments
  • I started here a set of tutorials for beginners:

    Day 0

    Day 1

    — answered August 11th 2010 by Dan Tamas
    permalink
    0 Comments
  • The iPhone simulator will re-load some changes you've made to JavaScript files without having to build the app each time. This is really useful if you want to tweak the layout of icons.. just navigate away & back to the window you're opening.

    — answered August 11th 2010 by Matt Collinge
    permalink
    0 Comments
  • Posted a new tutorial

    Seven days with Titanium – day 2 – tables and pickers

    http://cssgallery.info/seven-days-with-titanium-–-day-2-tables-and-pickers/

    — answered August 17th 2010 by Dan Tamas
    permalink
    0 Comments
  • with some javascript combined with some already available ti-mobile standard view classes, you can build missing gui-elements on your own. i created a tabgroup that can be used on iDevices and Android, you can get it here:

    http://developer.appcelerator.com/question/46801/giving-to-the-community-custom-tabgroup-class-working-on-android-and-iphone

    — answered August 20th 2010 by Christian Sigl
    permalink
    0 Comments
  • When you post a question or needed helps from Q&A. Be specific about platform, SDK and device in questioned. Remember this Q&A comment section is horrible, you won't get notified on comment reply. Questions usually get ignored because of cumbersome feedback. So, state your question wisely and be specific.

    For instance,

    SDK 1.4.1, IOS 4, iphone 4

    — answered August 23rd 2010 by Daniel Lim
    permalink
    0 Comments
  • iPad 3.2 using SDK 1.4.x:

    • WebView may expand/collapse when animating a view. This can be avoided by hard-setting its width and height instead of "auto".

    • When having issues setting EventHandlers, I've found that adding a small delay between an object's creation and applying the event handlers can remedy this issue.

    • setting a View's zIndex doesn't currently work. To get around this I'll add a hidden layer above the view above the interactive view. When a View needs to appear above the others, I'll "remove" the view form it's current container, set the visibility to true for the hidden layer and "add" the View to it.

    • If you've created a Javascript class which contains references to Views..etc. Event Listeners do not maintain scope which results in e.source returning "undefined". Following the Kitchen sink example code structure seems to be the best route.

    Hope these help someone out.

    — answered August 27th 2010 by Jag Lavek
    permalink
    0 Comments
  • Just launched my new webpage where I will publish tutorials for Titanium Mobile and thoughts of mobile development and user experiences in general.

    First post is up, Basic CRUD operations in Titanium Mobile.

    — answered October 5th 2010 by Adam Renklint
    permalink
    1 Comment
    • New post about module based development with Titanium Mobile.

      Please read and comment with your thoughts and ideas on this issue, I believe there's way too little discussion about the possibilities of Titanium out there.

      — commented October 8th 2010 by Adam Renklint
  • After a long delay I managed to publish day 4 in my tutorial series

    Seven days with Titanium – day 4 – Media – images, movies and sounds

    http://cssgallery.info/seven-days-with-titanium-–-day-4-–-media-–-images-movies-and-sounds/

    — answered November 6th 2010 by Dan Tamas
    permalink
    0 Comments
  • Just published my latest tutorial, Create a basic model with Titanium Mobile, which is the first in a series of posts where we get familiar with a MVC based approach to development.

    — answered November 6th 2010 by Adam Renklint
    permalink
    1 Comment
    • @Adam your link no more exists.

      — commented November 3rd 2013 by Muhammad Adnan
  • Using some kind of MVC for source code organization and project structure.

    — answered November 11th 2010 by Andre Carregal
    permalink
    0 Comments
  • xhr with login

    http://www.tine20.org/forum/viewtopic.php?f=12&t=4608&p=18980#p18980

    — answered November 16th 2010 by Kay Strobach
    permalink
    0 Comments
  • perhaps it helps
    http://www.tine20.org/forum/viewtopic.php?f=12&t=4608&p=18980#p18980

    — answered November 16th 2010 by Kay Strobach
    permalink
    0 Comments
  • Hand coding the XML language files to support internationalization seems like it would be a pain. So, I wrote a web page to do the busy work for me.

    Info here on my Tumblr page and the actual tool on my web site.

    — answered January 11th 2011 by Tim Poulsen
    permalink
    0 Comments
  • I'm working with Android 2.2 APIs and Titanium 1.5.1.

    Was trying to change the text of a label via an options dialogue. For example, when the label is clicked, an options dialogue appears and lets the user choose an option which changes the text shown in the label.

    I found out that clicking the 'back' button will force the label to some weird number -26458. You can add an if statement ( if (parseInt(e.value)>0 ) to avoid this number from appearing in your label.

    — answered February 9th 2011 by Zheng Da Clinton Goh
    permalink
    0 Comments
  • Use accelerated pickers: if you have a picker that is being used for a long-ish list of dollar values (ex: how much do you save each month for 'xxx'), you can create a picker whose values start out with $25 increments, then at some point increment by $50, then by $100, so that scrolling the picker moves in an accelerated fashion, and it is faster to get to larger amounts. IWO, at the $100 level $25 is a pretty big difference; but the same percent change at $1,000 would be $250.

    — answered February 9th 2011 by Richard Baughman
    permalink
    0 Comments
    1. If something doesn't seem to be working, try clearing out your build/iphone/ directory to perform a full-rebuild. (Want: an option in Titanium Developer to do this for me)
    2. Test on the device. The device will be slower, but more importantly has less memory than your machine with the emulator.
    — answered March 22nd 2011 by Kelvin Jones
    permalink
    0 Comments
  • When importing an existing project, make sure it at least has a /build/iphone or /build/android folder structure or the Run Emulator is blank.

    At least that's been my experience.

    — answered March 22nd 2011 by Erick Smith
    permalink
    0 Comments
  • Ahoi! To the rescue! The Tweetie-like pull to refresh example is only for iPhone. However! For a pull-to-refresh for Android see my gist here:

    http://gist.github.com/903895

    Do note that it's just an example, so for it to work with someones app it will need some modification. Hope this helps! Cheers!

    — answered April 5th 2011 by Joe iEntry
    permalink
    0 Comments
  • When rightNavButton or leftNavButton appear under barImage after closing a tab or a navgroup window, set yourWindow.barImage = ""; at closing to solve the issue.

    — answered April 6th 2011 by Thomas Bullier
    permalink
    0 Comments
  • I was getting fed up with converting Dates to Text in order to store in a property (and then convert back on retrieval), so with a bit of experimentation I noticed that using a 'list' allows you to store dates & times without having to convert. See below:

    https://gist.github.com/911293

    — answered April 15th 2011 by Chris Reed
    permalink
    0 Comments
  • In Google Maps, when you want WALKING directions rather than driving directions (default) append your URL request with &dirflg=w.

    — answered April 21st 2011 by Liz Myers
    permalink
    0 Comments
  • On iOS, When trying to share using Facebook don't forget to set the Bundle ID that's a very important lesson i've learned today :)

    — answered May 17th 2011 by Rafael Cardoso
    permalink
    0 Comments
  • This saved my life. Really.

    — answered June 26th 2011 by Umberto Gonnella
    permalink
    0 Comments
  • Based on what few sources I found, I learned how to create a pop-up date picker. It can easily be modified for use with custom rows as well.
    Titanium Studio iOS date picker. I posted the process and code on my blog.

    — answered August 18th 2011 by Michael Stelly
    permalink
    0 Comments
  • One of the biggest mistakes developers make when first starting with Titanium (myself included) is they do not include their shared classes in a global context, so they have to include them in each new window that they create/open. This mistake is perpetuated by the fact that the Kitchen Sink app works this way, when really it is there to show examples of how to use the API, not for how to structure an application.

    Follow an application model like Tweetanium or Ti.Air to create a global context that can be accessed in any view. This will save a lot of trouble in terms of performance and memory issues.

    — answered January 23rd 2012 by Justin Toth
    permalink
    1 Comment
    • Unfortunately, with Titanium's implementations of CommonJS principles and modules, global variables are no longer an option as CommonJS does not support global variables. Yes, they work in iOS, but that is actually a bug; they're not supposed to.

      And yes, I agree. Major bummer. :/

      — commented May 23rd 2012 by Brady Higginbotham
  • Just found out and honestly feel dumb about it: Close Titanium Studio/Developer. Then restart your simulator/emulator. Your app should be performing much better and as expected.
    I don't know why this happens but it does.

    — answered February 28th 2012 by Nikhil Nigade
    permalink
    0 Comments
  • Just found out and honestly feel dumb about it: Close Titanium Studio/Developer. Then restart your simulator/emulator. Your app should be performing much better and as expected.
    I don't know why this happens but it does.

    — answered February 28th 2012 by Nikhil Nigade
    permalink
    0 Comments
  • You are not able to run gif in Titanium android and iOS ? No Problem at all…We have solution :)
    It is basically a custom activity indicator/loader that can run both for android iOS any SDK
    you just need to add/change gif in the given path and all done.
    Try This and Enjoy.

    var tabGroup = Titanium.UI.createTabGroup();
    
    var win = Titanium.UI.createWindow({
        title : 'Tab',
        backgroundColor : '#fff'
    });
    
    var tab = Titanium.UI.createTab({
        icon : 'KS_nav_views.png',
        title : 'Tab',
        window : win
    });
    
    var webview = Ti.UI.createWebView({
        left : 110,
        height : 100,
        width : 100,
        zIndex : 10,
        contentWidth : 100,
        contentHeight : 100,
        top : 170,
        html : '<html><body><img style="background-color=#CCC margin-left=0px; " width="80" height="80" src="images/loading86.gif"></body></html>'
    });
    
    var controller = Ti.UI.createButton({
        title : 'Start',
        height : 40,
        width : 100,
        top : 300,
        left : 110
    });
    
    controller.addEventListener('click', function() {
    
        if (this.title == 'Start') {
            this.title = 'Stop';
            win.add(webview);
        } else {
            this.title = 'Start';
            win.remove(webview);
        }
    });
    
    win.add(controller);
    tabGroup.addTab(tab);
    tabGroup.open();
    

    Cheers..

    — answered January 22nd 2014 by Ali Akram
    permalink
    0 Comments
  • cool table tows with dynamic colors.

    var j=0; function itemGeneration(name,status,email) {
    var colors; if(j==0){ j++; colors='#F5FBEF'; } else{ j=0; colors='#FFFFFF'; }

    var row=Ti.UI.createTableViewRow({title:name,backgroundColor:colors});
    var itemOne=Ti.UI.createLabel({
    text:name,
    left:0,
    color:'#000000'
    });
    var itemTwo=Ti.UI.createLabel({
    text:status,
    right:0,
    color:'#000000'
    });

    var itemThree=Ti.UI.createLabel({ text:email, color:'#000000', center:'0' });

    row.add(itemOne);
    row.add(itemTwo);
    row.add(itemThree);

    // tblView.appendRow(row);

    $.table.appendRow(row);

    }

    — answered October 17th 2014 by Thilina Waasalage
    permalink
    0 Comments
  • cool table tows with dynamic colors.

    var j=0; function itemGeneration(name,status,email) {
    var colors; if(j==0){ j++; colors='#F5FBEF'; } else{ j=0; colors='#FFFFFF'; }

    var row=Ti.UI.createTableViewRow({title:name,backgroundColor:colors});
    var itemOne=Ti.UI.createLabel({
    text:name,
    left:0,
    color:'#000000'
    });
    var itemTwo=Ti.UI.createLabel({
    text:status,
    right:0,
    color:'#000000'
    });

    var itemThree=Ti.UI.createLabel({ text:email, color:'#000000', center:'0' });

    row.add(itemOne);
    row.add(itemTwo);
    row.add(itemThree);

    // tblView.appendRow(row);

    $.table.appendRow(row);

    }

    — answered October 17th 2014 by Thilina Waasalage
    permalink
    0 Comments
  • I used on the forms to customize the hint text instead of using the default. The only thing I haven't figured out is why it only works on iOS. Posting it because I thought it would be something useful for some :)

        // On focus hide the Picker and emulate the "hintText" behavior
        aTextField_Name.addEventListener('focus', function(e) {
    
            if (aTextField_Name.value == 'Hint Text Goes Here') {
                aTextField_Name.value = '';
            }
        });
        // On blur emulate the "hintText" behavior
        aTextField_status.addEventListener('blur', function(e) {
            if (aTextField_Name.value == '') {
                aTextField_Name.value = 'Hint Text Goes Here';
            }
        });
    
    — answered November 27th 2014 by F. F.
    permalink
    1 Comment
    • Sorry saw small error :)

      // On focus hide the Picker and emulate the "hintText" behavior
          aTextField_Name.addEventListener('focus', function(e) {
      
              if (aTextField_Name.value == 'Hint Text Goes Here') {
                  aTextField_Name.value = '';
              }
          });
          // On blur emulate the "hintText" behavior
          aTextField_Name.addEventListener('blur', function(e) {
              if (aTextField_Name.value == '') {
                  aTextField_Name.value = 'Hint Text Goes Here';
              }
          });
      

      — commented November 27th 2014 by F. F.
  • nice one

    — answered December 9th 2011 by Rahul Pandey
    permalink
    0 Comments
  • Can't find an RSS/article so: Sub me… =)

    /J

    — answered August 17th 2010 by Joacim Boive
    permalink
    0 Comments
  • Thumbs up for this thread. Keep 'em coming. :) Thanks!

    — answered August 17th 2010 by Felipe Apostol
    permalink
    0 Comments
  • I learned a new lesson today:
    When you think everything is correct but your program still crashes in Titanium Studio, try to compile your code with Titanium Developer.

    — answered July 4th 2011 by Mel Maxwell
    permalink
    6 Comments
    • Doesn't both of them call the same compilation script? What would contribute to this improvement?

      — commented July 4th 2011 by Shamsul Azhar Ahmad Shamsuddin
    • I really have no idea about that. Logically you're correct since they both use the same SDK( my case: SDK 1.6) to compile. But you can't depend o logic since Titanium is still very buggy. When I was stuck, I had to try everything.

      Below is the thread about the problem I faced with Titanium Studio.
      http://developer.appcelerator.com/question/121970/single-window-application-declaration

      — commented July 4th 2011 by Mel Maxwell
    • Developer is alot better then studio when it comes to reliability, give the devs some time.

      — commented July 4th 2011 by Kami -
    • Are you sure both methods were using the same SDK level? My guess here is one of two things explain what you saw:

      • The SDK level was different and the one you used in Studio has an issue not in the one you used while in Developer
      • Developer forced a full compile when it saw the timestamp on the tiapp.xml had changed, and the full compile "fixed" the problem

      A full compile might easily explain it even if the SDKs were different. It may be both SDK versions are fine but just forcing a full compile solved your issue.

      — commented July 4th 2011 by Doug Handy
    • From my own experience, SDK 1.7.* causes a lot of random crashing (Bus Error) even in the ios simulator. The same code runs solid under 1.6.2. :(

      — commented July 4th 2011 by Shamsul Azhar Ahmad Shamsuddin
    • I might have sounded like complaining, but I wasn't. Indeed, I love Titanium because it makes coding in phone format a lot simpler.

      — commented July 4th 2011 by Mel Maxwell
  • this is awesome.

    — answered December 9th 2011 by Rahul Pandey
    permalink
    0 Comments
  • — answered April 21st 2011 by Liz Myers
    permalink
    0 Comments
    • subscribe -
    — answered November 1st 2010 by Jicks Steen
    permalink
    0 Comments
The ownership of individual contributions to this community generated content is retained by the authors of their contributions.
All trademarks remain the property of the respective owner.