Learning Appcelerator Part 1 (Bio Authentication)

So you want to learn Appcelerator? Well this tutorial will teach you some of the basics to get you up and running creating Android and iOS apps.

What you will learn in part one.
In this tutorial we will learn some basic controls and how to make your app use the built in bio authentication provided by iOS (touch and face recognition).

You can download the starter framework and assets here.
Lets get started.

Prerequisites

  • You will needed to install Appcelerator Studio and have all the correct SDK’s installed. If you haven’t done that check out my post on some steps to get started.
  • You will of course need xCode
  • If you want to test on the simulators I recommend genymotion for android, and the built in iOS simulator that comes with xCode.

The Code

View (index.xml)

Lets start by adding some components to the view. The main components that we want to focus on are the TextFields the Labels and the Buttons.

INDEX.XML
<Alloy>
    <Window class="container" layout="vertical">
    	<ImageView id="bannerImgView"/>
        <Label id="userNmLbl"/>
        <TextField id="userNmTxt"/>
        <Label id="passwordLbl"/>
        <TextField id="passWrdTxt" onReturn="authenticate"/>
        <Button id="loginBtn" onClick="authenticate" class="allButtons"/>
        <Button id="thumbprintBtn" platform="ios" onClick="thumbPrint" visible="false"/>
    </Window>
</Alloy>

We will want to add event handlers to the Buttons and last TextField so that we can trigger the authentication functions we will be adding later.

Now that we have out framework laid out we need to style it. So open up the app.tss, in here is where well be putting code that should be used to effect application wide style.

APP.TSS
"Label": {
	"color": "#000", // all platforms except Android and Windows default to black
	"height": "45",
	"width": "50%",
	"font": {
		"fontSize": "14"
	}
},
"#bannerImgView": {
	"image": "/images/banner.png",
	"width": "100%"
},
"TextField": {
	"color": "black",
	"height": "45",
	"width": "41.33%"
},
".allButtons": {
	"height": "40",
	"width": "41.33%"
}

Next we will want to give specific styling to our screen. Each screen will have its own .tss file that can be used to callout specific elements and styling on that screen. Since our login screen is named index.js and index.xml out styling screen is named index.tss. In here is where you will put your code to specifically style that screen.

For you web developers out there you will notice it looks a lot like CSS. However it is NOT CSS but if it helps you can think of it as CSS just watch out because there a few differences that can trip you up. So you see like CSS we use the . and the # to denote Classes and ID’s. But we can also use code to specify things like returnKeyType and autocapitalization these are Titanium constance that can be used inside our .tss code

INDEX.TSS
".container" : {
	"backgroundColor" : "#fff",
	"top": "6%"
},
"#userNmLbl": {
	"text": "User Name",
	"top": "10%",
	"center": "50%",
	"textAlign": "center"
},
"#userNmTxt": {
	"borderRadius": "10",
	"borderColor": "#E5E5E5",
	"borderWidth": "1",
	"center": "50%",
	"returnKeyType": Titanium.UI.RETURNKEY_NEXT,
	"suppressReturn": "true",
	"autocapitalization": Titanium.UI.TEXT_AUTOCAPITALIZATION_NONE
},
"#passwordLbl": {
	"text": "Password",
	"center": "50%",
	"textAlign": "center"
},
"#passWrdTxt": {
	"borderRadius": "10",
	"borderColor": "#E5E5E5",
	"borderWidth": "1",
	"center": "50%",
	"returnKeyType": Titanium.UI.RETURNKEY_GO,
	"autocapitalization": Titanium.UI.TEXT_AUTOCAPITALIZATION_NONE,
	"passwordMask": "true"
},
"#loginBtn":{
	"title": "Sign In",
	"center": "50%",
	"top" : "5"
},
"#thumbprintBtn": {
	"top": "5",
	"center": "50%",
	"height": "50",
	"width": "50",
	"backgroundImage": "/images/fingerprint.png",
	"backgroundColor": "transparent"
},
"#thumbprintBtn[if=Alloy.Globals.isIphoneX]": {
	"backgroundImage": "/images/faceId.png",
}

Most of the code above is pretty self explanatory. However, I will point out a few things that might have you scratching your head.
"#thumbprintBtn[if=Alloy.Globals.isIphoneX]" This is iPhone X specific image that i want to add to the login screen ONLY if its iPhone X. The way to do this is to test for the device and then override the base backgroundImage with my new backgroundImage. Just like CSS last out wins. So the order of operation in .tss is top down. In this way we can define a backgroundImage as "backgroundImage": "/images/fingerprint.png" but if we discover that its iPhone X (in this case) we can override that image with "backgroundImage": "/images/faceId.png". We will define what that if condition is in the alloy.js file but for now just understand that if can be anything you want it to be as long as it evaluates to true or false.

Controller (index.js)

In your controller you want to start by adding a constructor. This insures we scope any variables that we don’t want to be public. Name it want ever you want I named mine “main”.
We are also defining two variables TouchId and TiAuth TouchId is a module we will be adding in our tiapp.xml later.

INDEX.JS
var TouchId = require("ti.touchid"),
    TiAuth = {};

//constructor
(function main() {})();

Next lets add our functions we defined onClick events for in our view

INDEX.JS
function thumbPrint(e) {
	TiAuth.doBioAuth();
}

function authenticate(e) {
	TiAuth.doAuth();
}

If you are wondering what those “do” functions are those private name spaced functions that we will be adding inside our main function.

Now lets add our private functions. This will be scoped inside of the namespace TiAuth (name it what ever you want) This way you can’t access them outside of that namespace and it makes them more secure and private. I wanted to be able to use the login button or the bio authentication (fingerprint or face recognition).

INDEX.JS

TiAuth.doBioAuth = function() {
};

TiAuth.doAuth = function(didPassBio) {
};

Next we will add the magic that will authenticate using biometrics. Here we use the TouchId module to authenticate. There are a few options we can set, and different cases it might fail. I won’t go into all of them as they are self explanatory. But you can choose to add them or not.

if (OS_IOS && TouchId.isSupported()) {
    TouchId.authenticate({
        reason: "Login to this application",
        allowableReuseDuration: 2, // iOS 9+, optional, in seconds, only used for lockscreen-unlocks
        fallbackTitle: "Use different auth method?", // iOS 10+, optional
        cancelTitle: "No thanks", // iOS 10+, optional
        callback: function(e) {
            if (!e.success) {
                switch (e.code) {
                    case TouchId.ERROR_AUTHENTICATION_FAILED:
                        Ti.API.info('Error code is TouchId.ERROR_AUTHENTICATION_FAILED');
                        break;
                    case TouchId.ERROR_USER_CANCEL:
                        Ti.API.info('Error code is TouchId.ERROR_USER_CANCEL');
                        break;
                    case TouchId.ERROR_USER_FALLBACK:
                        Ti.API.info('Error code is TouchId.ERROR_USER_FALLBACK');
                        break;
                    case TouchId.ERROR_SYSTEM_CANCEL:
                        Ti.API.info('Error code is TouchId.ERROR_SYSTEM_CANCEL');
                        break;
                    case TouchId.ERROR_PASSCODE_NOT_SET:
                        Ti.API.info('Error code is TouchId.ERROR_PASSCODE_NOT_SET');
                        break;
                    case TouchId.ERROR_TOUCH_ID_NOT_AVAILABLE:
                        Ti.API.info('Error code is TouchId.ERROR_TOUCH_ID_NOT_AVAILABLE');
                        break;
                    case TouchId.ERROR_TOUCH_ID_NOT_ENROLLED:
                        Ti.API.info('Error code is TouchId.ERROR_TOUCH_ID_NOT_ENROLLED');
                        break;
                    case TouchId.ERROR_TOUCH_ID_NOT_ENROLLED:
                        Ti.API.info('Error code is TouchId.ERROR_TOUCH_ID_NOT_ENROLLED');
                        break;
                    case TouchId.ERROR_APP_CANCELLED:
                        Ti.API.info('Error code is TouchId.ERROR_APP_CANCELLED');
                        break;
                    case TouchId.ERROR_INVALID_CONTEXT:
                        Ti.API.info('Error code is TouchId.ERROR_INVALID_CONTEXT');
                        break;
                    case TouchId.ERROR_TOUCH_ID_LOCKOUT:
                        Ti.API.info('Error code is TouchId.ERROR_TOUCH_ID_LOCKOUT');
                        break;
                    default:
                        Ti.API.info('Error code is unknown');
                        break;
                }
            } else { //success
                TiAuth.doAuth(true);
            }
        }
    });
}



TiAuth.doAuth = function(didPassBio) {
    if (password == $.passWrdTxt.value && userName == $.userNmTxt.value || didPassBio) {
        alert("You have successfully logged in!");
    } else {
        alert("You have failed to login!");
    }

};

Lastly you see the doAuth(). This is where we finalize the auth. I’m checking for the password and username but if they authenticated via bio metrics then i allow access.

Model

Nothing to see here (yet)

Global

Now lets talk about the alloy.js file is the initializer file for the application. The initializer file app/alloy.js can be used to execute some code near the beginning of the application’s lifecycle. The contents of this file will be executed right before the initial index.js controller is loaded, allowing you to execute code before any UI components are loaded and to override builtin Alloy functions before they are executed. The code in this file also has access to the Alloy namespace.

This is the perfect place to put our iPhone X code. This will determine if the screen size of our iOS device is taller then we can assume its the iPhone X. So we namespace it using the Alloy.Globals (An object for storing globally accessible variables and functions) and now we can access it anywhere in our code.

ALLOY.JS

Alloy.Globals.isIphoneX = (Ti.Platform.displayCaps.platformHeight == 812);

The full source code for this project can be gotten here.

Loading Facebook Comments ...