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

You must Login before you can answer or comment on any questions.

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 5 years ago by Dan Tamas
3 Comments
  • Beginnings of a collection of Javascript debug helpers:

    http://appcelerated.wikispot.org/Debugging

    — commented 4 years ago by Alan Bourke

  • I created these SearchPlugins for your browser (compatible with Firefox, Chrome, IE7 & IE8) that I use all the time.

    — commented 4 years ago 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 4 years ago by Alan Bourke

75 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 4 years ago by Matt Collinge
answer 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 1 year ago 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

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 3 years ago by Kami -
answer permalink
3 Comments
  • Google Maps URL contains two typos, should be

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

    — commented 3 years ago by Julien Nebbout

  • works on android, will give you the option to open it in the browser or in the map application

    — commented 3 years ago by Blueshift Local

  • operUrl is wrong method...correct method is openURL

    — commented 8 months ago 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 4 years ago by Ganna Kozynenko
answer permalink
3 Comments
  • These sound like very good tips. Does anyone have examples on how to implement them?

    — commented 4 years ago 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 3 years ago 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 3 years ago 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!

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 4 years ago by John Welch
answer permalink
2 Comments
  • this doesn't look like standard.

    — commented 4 years ago 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 4 years ago 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 4 years ago by Critter .
answer permalink
2 Comments
  • Easier way...

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

    — commented 4 years ago by Justin Toth

  • Maybe use this one:

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

    — commented 3 years ago 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.

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 4 years ago by Joe iEntry
answer permalink
5 Comments
  • Thanks! I didn't know about 'simple' vs. 'standard' table views.

    — commented 4 years ago 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 4 years ago 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 3 years ago by Jason Harrelson

  • Show 2 more comments

I have a new tutorial on how to create a tooltip.

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

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 4 years ago by Tim Poulsen
answer 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 2 months ago 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!

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();
});

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 4 years ago by Matt Collinge
answer 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 4 years ago 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 4 years ago by Daniel Lim
answer permalink
3 Comments
  • Nice tip. Could this be a bug in Titanium? Or should it work like this?

    — commented 4 years ago 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 4 years ago by Chris Campbell

  • This is definitely a bug.

    — commented 4 years ago by Ernesto Mendoza

Written a small snippet to extract / parse and deploy KML data on a maps via javascript

here is the link

inline

Beginnings of a collection of Javascript debug helpers:

http://appcelerated.wikispot.org/Debugging

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

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.

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 5 years ago by Ryan Gartin
answer 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 3 years ago by Michael Stelly

  • alert() works great on all platforms

    — commented 3 years ago 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"

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.

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

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.

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.

Hi i have created a tutorial on how to perform orientation changes on android.

Here is the link

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 4 years ago by alessio ricco
answer permalink
1 Comment
  • The requested page cannot be accessed because the related configuration data for the page is invalid.

    — commented 4 months ago 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();

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

  • 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 4 years ago by Luke Days
answer 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 4 years ago 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.

The Titanium Studio shortcut Ctrl + F11 exectute the last "run command". Usefull, if you want restat your app inside the Simulator/Emulator.

— answered 3 years ago by A S
answer permalink
1 Comment
  • Of course on a MAC it's CMD + F11, with the fn key held depending on keyboard settings

    — commented 3 years ago 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...

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

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

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.

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/

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

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

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.

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.

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/

xhr with login

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

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

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.

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.

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.

  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.

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.

When rightNavButton or leftNavButton appear under barImage after closing a tab or a navgroup window, set yourWindow.barImage = ""; at closing to solve the issue.

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

In Google Maps, when you want WALKING directions rather than driving directions (default) append your URL request with &dirflg=w.

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 :)

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 3 years ago by Justin Toth
answer 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 2 years ago 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.

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.

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..

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 3 years ago by Mel Maxwell
answer permalink
6 Comments
  • Doesn't both of them call the same compilation script? What would contribute to this improvement?

    — commented 3 years ago 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 3 years ago by Mel Maxwell

  • Developer is alot better then studio when it comes to reliability, give the devs some time.

    — commented 3 years ago by Kami -

  • Show 3 more comments

Your Answer

Think you can help? Login to answer this question!