You are on page 1of 58

Titanium Mobile

Javascript

Justin Lee

Mobile App?

JAVAObjective-C


Web App

Hybrid App

Native App

HTML5+CSS+JS

HTML5+CSS+JS+JS API

Java, Obj-C+Native API

...


UI

window webview DOM parser JavaScript interpreter CSS parser HTML renderer SVG renderer Canvas renderer history manager SQLLite engine index.html render window label

window label window label hello world!

web

Titanium Mobile


JavaScript
var win = Titanium.UI.createWindow({ backgroundColor:'#fff' }); var label = Titanium.UI.createLabel({ text: 'Hello World!' }); win.add(label); win.open();

Titanium
Javascript+
Titanium API

JS to Native Bridge
Native API


iPhone, iPad, AndroidBlackBerry


UI APIPhone API


50%


JavaObjective-CTitanium API

Titanium
SDK
Titanium Mobile SDK (1.6.2) iOS SDK or Android SDK

Developer Tool
Titanium Developer (1.2.2) Titanium Studio (RC1)

textmate, vim...

iOSMac

Titanium Developer

Titanium Studio
Breakpoint+Debugger

Titaniumjavascript
DOMJQuery UIJavascript window viewdiv AddEventListener execution context


Hello World! Titanium


HowIsTheWeather/ build/ android/ ... iphone/ ... CHANGELOG.txt LICENSE LICENSE.txt manifest README Resources/ android/ ... app.js iphone/ ... KS_nav_ui.png KS_nav_views.png tiapp.xml

android iphone

Hello World!
var win = Titanium.UI.createWindow({ backgroundColor:'#fff' }); var label = Titanium.UI.createLabel({ text: 'Hello World!', textAlign: 'center' }); label.addEventListener('click', function(e){ Titanium.API.info('label clicked!'); }); win.add(label); win.open();

http://goo.gl/0be5C

Titanium

http://goo.gl/Fj3pl

UI GPS XML

UI
var win = Titanium.UI.createWindow({ backgroundColor:'#fff' }); var locationLabel = Titanium.UI.createLabel({ color:'#000', text:'', font:{fontSize: 30, fontFamily:'Helvetica Neue'}, textAlign:'center', width:'auto', height: 'auto', left: 15, top: 75 });

75px 15px

var weatherIcon = Titanium.UI.createImageView({ image: 'images/mostly_cloudy.gif', width: 80, height: 80, left: 15, top: 120 });

UI ()
var temperatureLabel = Titanium.UI.createLabel({ color:'#000', text:'28C', font:{fontSize: 90, fontFamily:'Helvetica Neue'}, textAlign:'center', width:'auto', height: 'auto', right: 15, top: 100 }); var detailLabel = Titanium.UI.createLabel({ color:'#000', text: '\n 62%\n \n10 /', font:{fontSize: 24, fontFamily:'Helvetica Neue'}, textAlign:'left', width:'auto', height: 'auto', left: 20, top: 220 }); win.add(locationLabel); win.add(weatherIcon); win.add(temperatureLabel); win.add(detailLabel); win.open();


if (Titanium.Geolocation.locationServicesEnabled === false) { Titanium.UI.createAlertDialog({title:'', message:''}).show(); } else { Ti.Geolocation.purpose = "get current position"; Titanium.Geolocation.accuracy = Titanium.Geolocation.ACCURACY_THREE_KILOMETERS;

iOS 3.2

Titanium.Geolocation.distanceFilter = 1000;

Titanium.Geolocation.getCurrentPosition(function(e) { if (e.error) { Titanium.API.info("error: " + JSON.stringify(e.error)); return; } var latitude = e.coords.latitude; var longitude = e.coords.longitude; Ti.API.info(longitude+','+latitude); }); ... }


function updateLocationName(lat, lng) { Titanium.Geolocation.reverseGeocoder(lat, lng, function(e) { if (e.success) { var places = e.places; if (places && places.length) { locationLabel.text = places[0].city; } else { locationLabel.text = ""; } Ti.API.debug("reverse geolocation result = "+JSON.stringify(e)); } else { Ti.UI.createAlertDialog({ title:'Reverse geo error', message:evt.error }).show(); Ti.API.info("Code translation: "+translateErrorCode(e.code)); } }); }

Googles secret Weather API


http://www.google.com/ig/api?hl={locale}&weather=,,,{lat},{lng}
http://www.google.com/ig/api?hl=zh-tw&weather=,,,25060808,121485606
<?xml version="1.0"?> <xml_api_reply version="1"> <weather module_id="0" tab_id="0" mobile_row="0" mobile_zipped="1" row="0" section="0" > <forecast_information> <city data=""/> <postal_code data=""/> <latitude_e6 data="25060808"/> <longitude_e6 data="121485606"/> <forecast_date data="2010-09-15"/> <current_date_time data="2010-09-14 23:00:00 +0000"/> <unit_system data="SI"/> </forecast_information> <current_conditions> <condition data=""/> http://img0.gmodules.com/ <temp_f data="79"/> <temp_c data="26"/> <humidity data=" 87%"/> <icon data="/ig/images/weather/cloudy.gif"/> <wind_condition data=" /"/> </current_conditions> <forecast_conditions> <day_of_week data=""/> <low data="26"/> <high data="35"/> <icon data="/ig/images/weather/thunderstorm.gif"/> <condition data=""/> </forecast_conditions> ... </weather> </xml_api_reply>


function updateWeather(lat, lng) { var xhr = Titanium.Network.createHTTPClient(); xhr.onload = function() { Ti.API.info('weather xml ' + this.responseXML + ' text ' + this.responseText); //var doc = this.responseXML.documentElement; encoding bug on Android var doc = Titanium.XML.parseString(this.responseText).documentElement; var condition = doc.evaluate("//weather/current_conditions/condition").item (0).getAttribute('data'); Ti.API.info(condition); ... temperatureLabel.text = temp_c + 'C'; weatherIcon.image = icon; detailLabel.text = condition + '\n'; detailLabel.text += humidity + '\n'; detailLabel.text += wind_condition.split('')[0] + '\n'; detailLabel.text += wind_condition.split('')[1] + '\n'; }; var url = 'http://www.google.com/ig/api?hl=zh-tw&weather=,,,'+parseInt(lat*1000000, 10)+','+parseInt(lng*1000000, 10); Ti.API.info(url); xhr.open('GET', url); xhr.send();


function getCurrentWeather() { if (Titanium.Geolocation.locationServicesEnabled === false) { Titanium.UI.createAlertDialog({title:'', message:''}).show(); } else { Ti.Geolocation.purpose = ""; Titanium.Geolocation.accuracy = Titanium.Geolocation.ACCURACY_BEST; Titanium.Geolocation.distanceFilter = 1000; Titanium.Geolocation.getCurrentPosition(function(e) { if (e.error) { Titanium.API.info("error: " + JSON.stringify(e.error)); Titanium.UI.createAlertDialog({title:'', message: e.error.message}).show(); detailLabel.text = ''; return; } var latitude = e.coords.latitude; var longitude = e.coords.longitude; Ti.API.info(longitude+','+latitude); updateLocationName(latitude, longitude); updateWeather(latitude, longitude); }); } }

getCurrentWeather(); updateInterval = setInterval(getCurrentWeather, 300000);


var settingWin = Titanium.UI.createWindow({ backgroundColor: '#999' }); var aboutWebview = Titanium.UI.createWebView({ url: 'about.html', ... }); settingWin.add(aboutWebview); var doneButton = Titanium.UI.createButton({ title: '', ... }); settingWin.add(doneButton);

doneButton.addEventListener('click', function(e){ if(Titanium.Platform.osname === 'iphone') { settingWin.close({transition: Ti.UI.iPhone.AnimationStyle.FLIP_FROM_RIGHT}); mainWin.open(); }else if(Titanium.Platform.osname === 'android') { mainWin.open(); settingWin.close(); } getCurrentWeather(); });

iOS

WebView
<!doctype html> <html lang="zh-tw"> <head> <meta charset="utf-8"> <title>About</title> <meta name="description" content="About the app"> <meta name="viewport" content="width=320"/> <meta name="author" content="lis186"> <link rel="stylesheet" href="screen.css"> </head> <body> <h1></h1> <img src='appicon.png'> <p> 1.0</p> <p>Powered by Titanium Mobile.</p> </body> </html>

about.js

iPhone
if(Titanium.Platform.osname === 'iphone') { var unitTabbedBar = Titanium.UI.createTabbedBar({ labels:['C', 'F'], style:Titanium.UI.iPhone.SystemButtonStyle.BAR, ... }); unitTabbedBar.addEventListener('click', function(e){ if(e.index === 0) { Titanium.App.Properties.setString('tempUnit', 'c'); }else if (e.index === 1){ Titanium.App.Properties.setString('tempUnit', 'f'); } }); settingWin.add(unitTabbedBar); var settingButton = Titanium.UI.createButton({ ... style: Titanium.UI.iPhone.SystemButton.INFO_DARK }); mainWin.add(settingButton); }

iOS

Android
if(Titanium.Platform.osname === 'android') { var cButton = Titanium.UI.createButton({ title: 'C', ... }); var fButton = Titanium.UI.createButton({ title: 'F', ... }); cButton.addEventListener('click', function(e){ Titanium.App.Properties.setString('tempUnit', 'c'); cButton.enabled = false; fButton.enabled = true; }); fButton.addEventListener('click', function(e){ Titanium.App.Properties.setString('tempUnit', 'f'); cButton.enabled = true; fButton.enabled = false; }); settingWin.add(cButton); settingWin.add(fButton); }

UIiPhone
if(Titanium.Platform.osname === 'iphone') { mainWin.add(settingButton); settingButton.addEventListener('click', function(e){ settingWin.open({ transition: Ti.UI.iPhone.AnimationStyle.FLIP_FROM_LEFT }); var tempUnit = Titanium.App.Properties.getString('tempUnit', 'c'); if(tempUnit === 'c') { unitTabbedBar.index = 0; }else if(tempUnit === 'f') { unitTabbedBar.index = 1; } mainWin.close(); }); }

iOS

Property

UIAndroid
if(Titanium.Platform.osname === 'android') { Titanium.Android.currentActivity.onCreateOptionsMenu = function(e) { Titanium.API.info("create menu"); var menu = e.menu; var refreshMenuItem = menu.add({ title: '' }); var settingMenuItem = menu.add({ title: '' }); refreshMenuItem.addEventListener("click", function(e) { getCurrentWeather(); }); settingMenuItem.addEventListener("click", function(e) { indicator.hide(); settingWin.open(); var tempUnit = Titanium.App.Properties.getString('tempUnit', 'c'); if(tempUnit === 'c') { cButton.enabled = false; fButton.enabled = true; }else if(tempUnit === 'f') { cButton.enabled = true; fButton.enabled = false; } mainWin.close(); }); }; }

iOS background servicebadge


if(Titanium.Platform.osname === 'iphone') { var service; Titanium.App.addEventListener('pause',function(e) { Ti.API.info('pause'); service = Titanium.App.iOS.registerBackgroundService({ url: 'bgjob.js', tempUnit: Titanium.App.Properties.getString('tempUnit', 'c') }); Titanium.API.info("registered background service = "+service); }); Titanium.App.addEventListener('resumed',function(e) { Ti.API.info('resumed'); if(service != null){ getCurrentWeather(); service.stop(); service.unregister(); Ti.API.info('Stop background service'); } }); }

custom property

function updateWeather(lat, lng) { var xhr = Titanium.Network.createHTTPClient(); xhr.onload = function() {

bgjob.js
custom property

var tempUnit = Titanium.App.currentService.tempUnit;


... if(tempUnit === 'c') { Titanium.UI.iPhone.appBadge Ti.API.info('Update badge:' }else if(tempUnit === 'f') { Titanium.UI.iPhone.appBadge Ti.API.info('Update badge:' }

= temp_c; + temp_c);

= temp_f; + temp_f);

}; var url = 'http://www.google.com/ig/api?hl=zh-tw&weather=,,,'+ parseInt(lat*1000000, 10)+','+parseInt(lng*1000000, 10); Ti.API.info(url); xhr.open('GET', url); xhr.send(); } function getCurrentWeather() { ... } ... Ti.API.info('starting background service'); var updateInterval = setInterval(getCurrentWeather, 300000);

Androidresume

if(Titanium.Platform.osname === 'android') { Titanium.Android.currentActivity.addEventListener('resume', function(e) { Ti.API.info("resumed"); getCurrentWeather(); }); }

!== Write Once, Run Everywhere

http://www.cultofmac.com/self-evidently-bad-app-idea-scale-for-ipad

Titanium Mobile SDK

http://goo.gl/Se1dF
Kitchen Sink

http://goo.gl/5v6dJ

http://goo.gl/Fj3pl

Titanium Mobile()

6/9
http://www.lis186.com/?p=2140

ing! Hir ere W


Titanium SDK Developer Titanium Evangelist
http://ti.herxun.co/?page_id=66

You might also like