functional aspects of great native mobile apps

22
FUNCTIONAL ASPECTS OF GREAT NATIVE MOBILE APPS http://www.flickr.com/photos/ourcage/8343799386/

Upload: leslie-brice-heath

Post on 18-Dec-2015

220 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: FUNCTIONAL ASPECTS OF GREAT NATIVE MOBILE APPS

FUNCTIONAL ASPECTS OFGREAT NATIVE MOBILE APPS

http://www.flickr.com/photos/ourcage/8343799386/

Page 2: FUNCTIONAL ASPECTS OF GREAT NATIVE MOBILE APPS

Functionality to go from good to great

• Why create a native mobile app if you aren't going to use the hardware that is hard or impossible to access in a mobile web app?

• Other functional considerations related to creating great apps

• We'll continue the conversation about "great apps" in Unit 5.

Page 3: FUNCTIONAL ASPECTS OF GREAT NATIVE MOBILE APPS

Accessing phone hardware

• E.g., Compass, Geolocation, Accelerometer, Shake, Sound, Camera

• Some of these are robustly supported only in certain mobile browsers (e.g., compass in Safari) but available and reliable in native apps

• Others are available in most mobile browsers (e.g., geolocation), but more features are available in native apps

Page 4: FUNCTIONAL ASPECTS OF GREAT NATIVE MOBILE APPS

Compass

var win = Ti.UI.createWindow({backgroundColor : "#FFFFFF",title : "test"

});var lbl = Ti.UI.createLabel();win.add(lbl);win.open();

function display(e) {lbl.text = e.heading ? 'compass:' + e.heading.magneticHeading + ',when:' + (new Date()).getTime() : 'null heading';// see also the trueHeading property, used along with location tracking

}

// you can get heading just once with getCurrentHeading() or you can monitor it…Ti.Geolocation.addEventListener("heading", display);// use removeEventListener when done!!

Page 5: FUNCTIONAL ASPECTS OF GREAT NATIVE MOBILE APPS

Geolocation

function display(e) { lbl.text = e.coords ?

'lat:' + e.coords.latitude + ',lon:' + e.coords.longitude + ',when:' + (new Date()).getTime() : 'null coords';}

Ti.Geolocation.preferredProvider = Titanium.Geolocation.PROVIDER_GPS;Ti.Geolocation.purpose = "CS496";Ti.Geolocation.accuracy = Titanium.Geolocation.ACCURACY_BEST; // can use lower accuracyTi.Geolocation.distanceFilter = 10; // can use broader filter

if (Titanium.Geolocation.locationServicesEnabled === false) {alert('You need to turn GPS on.');

} else {

// to get location just onceTi.Geolocation.getCurrentPosition(display);

// to continually get locationTi.Geolocation.addEventListener('location', display);// unregister with Ti.Geolocation.removeEventListener(display) when done with it!

}

Page 6: FUNCTIONAL ASPECTS OF GREAT NATIVE MOBILE APPS

Accelerometer

• When the device isn’t accelerating, it’s more of a “gravity-meter” than an accelerometer

var listener = function(e) { lbl.text = 'accel: ' + e.x + ';' + e.y + ';' + e.z;};

Ti.Accelerometer.addEventListener('update', listener);

Ti.Accelerometer.removeEventListener('update', listener);

Page 7: FUNCTIONAL ASPECTS OF GREAT NATIVE MOBILE APPS

Shake

Ti.Gesture.addEventListener('shake', fn);

Ti.Gesture.removeEventListener(fn);

// No API for just retrieving once (obviously?)// Seems to only detect really strong shakes (?)

Page 8: FUNCTIONAL ASPECTS OF GREAT NATIVE MOBILE APPS

Key cautions

• Accessing this specialized hardware is very battery-intensive

• Option #1: Just retrieve value once– Use setTimeOut every few minutes if needed

• Option #2: Register for the event listener– Look into the specialized APIs for filtering events

• E.g., "only fire a geolocation event on change >100 meters"

– Unregister your event listener as soon as possible

Page 9: FUNCTIONAL ASPECTS OF GREAT NATIVE MOBILE APPS

Camera

var win = Ti.UI.createWindow({backgroundColor : "#FFFFFF",title : "test"

});

var btnCamera = Ti.UI.createButton({title : 'Take picture',top : 20

});

btnCamera.addEventListener('click', function() {Titanium.Media.showCamera({

success : function(event) {var photoTaken = event.media;

if (event.mediaType == Ti.Media.MEDIA_TYPE_PHOTO) {var imgView = Titanium.UI.createImageView({left : 10,width : 300,height : 300,image : photoTaken});

win.add(imgView);}},cancel : function(event) {alert('cancel');},error : function(event) {alert('error');}

});});

win.add(btnCamera);win.open();

Page 10: FUNCTIONAL ASPECTS OF GREAT NATIVE MOBILE APPS

Other functional considerations

• Great apps also have functionality for:– Validating inputs, managing state throughout an

application's lifecycle– Taking advantage of relevant specialized

user interface controls and views– Selectively applying platform-specific APIs

Page 11: FUNCTIONAL ASPECTS OF GREAT NATIVE MOBILE APPS

Input validation: Assuring that your app's state is initialized from user data correctly

• Sadly, form validation is very underdeveloped in Titanium

• Best approach is to:1. Add labels to your form, for showing error msgs2. In your button click handler, check every input

(e.g., with regular expressions)3. If an input is invalid, set an error message;

else, clear error message(s) and continue.

Page 12: FUNCTIONAL ASPECTS OF GREAT NATIVE MOBILE APPS

Handling lifecycle events

• Apps can be paused and then resumed– For example, if user goes to home screen and then

comes back to your app– iOS and Android have slightly different events, but

Titanium hides some of this from you

• On pause, – Save any state that cannot be lost, release resources

• On resume,– Reinitialize from saved state, reinitialize resources

Page 13: FUNCTIONAL ASPECTS OF GREAT NATIVE MOBILE APPS

Example of handling lifecycle events

Ti.App.addEventListener('pause',function(e) {// call removeEventListener for hardware// save user data to local storage

});Ti.App.addEventListener('resume',function(e) {

// reload user data from local storage// call addEventListener for hardware

});

Page 14: FUNCTIONAL ASPECTS OF GREAT NATIVE MOBILE APPS

You can also detect Android-specific lifecycle events

• Detecting your execution environmentfunction isAndroid() { // iOS vs Android

return Ti.Platform.name == 'android';}

• Accessing Android-specific events (another video will cover the Android lifecycle in detail)

Ti.Android.currentActivity.addEventListener('create', function(e) {// called when the app's current activity (window) is created

});Ti.Android.currentActivity.addEventListener('start', function(e) { … }); Ti.Android.currentActivity.addEventListener('resume', function(e) { … });Ti.Android.currentActivity.addEventListener('pause', function(e) { … });Ti.Android.currentActivity.addEventListener('stop', function(e) { … });

Page 15: FUNCTIONAL ASPECTS OF GREAT NATIVE MOBILE APPS

Speaking of which…

• Great apps take selective advantage of functionality that is platform-specific– Yes, this decreases portability– But it has the potential to improve the user

experience and benefits given to users

• And use specialized user interface controls – That might be rendered in platform-specific ways

Page 16: FUNCTIONAL ASPECTS OF GREAT NATIVE MOBILE APPS

Judicious use of specialization

• Specialization driven by guidelines & hardware– E.g., guidelines: iOS apps use toolbars to navigate– E.g., hardware: Android phones have 2+ buttons

• FYI, you can also specialize images– Depending on platform and screen density

(essentially dots per inch)– Customize using Resources subdirectories

Page 17: FUNCTIONAL ASPECTS OF GREAT NATIVE MOBILE APPS

ScrollViewRendered nearly the same on iOS & Android

var win = Ti.UI.createWindow({backgroundColor : "#FFFFFF",layout : 'vertical'

});

var scrollView = Ti.UI.createScrollView({contentWidth : 'auto',contentHeight : 'auto',showVerticalScrollIndicator : true,height : Ti.UI.FILL,width : Ti.UI.FILL,layout : 'vertical'

});for (var i = 0; i < 100; i++)

scrollView.add(Ti.UI.createLabel({text : "item " + i,color: '#000000'

}));win.add(scrollView);win.open();

Page 18: FUNCTIONAL ASPECTS OF GREAT NATIVE MOBILE APPS

PickerSame code, rendered differently on iOS & Android

var win = Ti.UI.createWindow({ backgroundColor: "#FFFFFF", layout: 'vertical'});

var picker = Ti.UI.createPicker({ selectionIndicator: true});

var items = [];items[0]=Ti.UI.createPickerRow({title:'OSU'});items[1]=Ti.UI.createPickerRow({title:'UO'});items[2]=Ti.UI.createPickerRow({title:'UW'});

picker.add(items);

win.add(picker);win.open();

Page 19: FUNCTIONAL ASPECTS OF GREAT NATIVE MOBILE APPS

TabGroupSame code, rendered differently on iOS & Android

// From the wizard-generated code…//create module instancevar self = Ti.UI.createTabGroup();

//create app tabsvar win1 = new Window(L('home')),win2 = new Window(L('settings'));

var tab1 = Ti.UI.createTab({title: L('home'),icon: '/images/KS_nav_ui.png',window: win1

});win1.containingTab = tab1;

var tab2 = Ti.UI.createTab({title: L('settings'),icon: '/images/KS_nav_views.png',window: win2

});win2.containingTab = tab2;

self.addTab(tab1);self.addTab(tab2);

You can just use Ti.UI.createWindow(…), FYI

Page 20: FUNCTIONAL ASPECTS OF GREAT NATIVE MOBILE APPS

CoverFlowViewOnly available on iOS

var win = Ti.UI.createWindow({backgroundColor : "#FFFFFF"

});

var imgs = [];for (var i = 1; i <= 3; i++)

imgs.push({image : 'img' + i + '.jpg',height : '33%',width : '33%'});

var view = Titanium.UI.iOS.createCoverFlowView({backgroundColor : '#00000',images : imgs,width : Ti.UI.FILL,height : Ti.UI.FILL

});win.add(view);win.open();

http://www.flickr.com/photos/musicbook/3525997685http://www.flickr.com/photos/kbcool/2226493331

http://www.flickr.com/photos/ranh/2390167998

Page 21: FUNCTIONAL ASPECTS OF GREAT NATIVE MOBILE APPS

ToolbarOnly available on iOS

var win = Ti.UI.createWindow({ backgroundColor : "#FFFFFF" });

var btnReview = Titanium.UI.createButton({title : 'Review',style : Titanium.UI.iPhone.SystemButtonStyle.DONE,

});// systemButton specifies a standard appearance (has nothing to do with behavior)var btnTrash = Titanium.UI.createButton({

systemButton : Titanium.UI.iPhone.SystemButton.TRASH,});var btnCancel = Titanium.UI.createButton({

systemButton : Titanium.UI.iPhone.SystemButton.CANCEL});var spacer = Titanium.UI.createButton({

systemButton : Titanium.UI.iPhone.SystemButton.FLEXIBLE_SPACE});var toolbar = Titanium.UI.iOS.createToolbar({

items : [btnCancel, spacer, btnTrash, spacer, btnReview],top : 0,borderTop : false,borderBottom : true

});win.add(toolbar);win.open();

Page 22: FUNCTIONAL ASPECTS OF GREAT NATIVE MOBILE APPS

MenuOnly available on Android

var win = Ti.UI.createWindow({fullscreen : true

});

var activity = win.activity;

activity.onCreateOptionsMenu = function(e) {var menu = e.menu;for (var i = 0; i < 4; i++) {

var menuItem = menu.add({title : "Choice " + i

});menuItem.addEventListener("click", function(e) {

alert("Your choice has been noted.")});

}};

win.open();