Determine if Intent Receiver Exists on Android using Titanium

One of the challenges in working with Ti.Android.Intent‘s is knowing if the device has an app installed that will be able to handle the request.  The recommended approach until now was to wrap your startActivity statement within a try/catch statement.

With the new Android.Tools module you can now check if a Ti.Android.Intent has a receiver before submitting. This allows you to write more defensive code blocks like the one below:

//Add our tools module
var tools = require('bencoding.android.tools');
var platformTools = tools.createPlatform();

//Check we have external storage access
if(!Ti.Filesystem.isExternalStoragePresent()){
	alert("Access to external storage required");
	return;
}

//Create a Ti.File to our sample file
var pdfSource = Ti.Filesystem.getFile(Ti.Filesystem.resourcesDirectory + 'your_file.pdf');
//Create a temp file so the intent can read the file
var timeStampName = new Date().getTime();
var tempFile = Ti.Filesystem.getFile(Ti.Filesystem.tempDirectory,timeStampName +'.pdf');
if(tempFile.exists()){
	tempFile.deleteFile();
}
tempFile.write(pdfSource.read());
pdfSource = null;

//Create our PDF intent
var intent = Ti.Android.createIntent({
	action: Ti.Android.ACTION_VIEW,
	type: "application/pdf",
	data: session.tempFile.nativePath
});

//Check that the device can open the intent
if(platformTools.intentAvailable(intent)){
	//Since the device can open the intent run startActivity
	try {
		Ti.Android.currentActivity.startActivity(intent);
	} catch(e) {
		Ti.API.debug(e);
		alert('Something went wrong');
	}
}else{
	//No PDF reader to we need to alert the user to go get one.
	alert("Please go to the Google Play Store and download a PDF reader");			
}

Android.Tools project

Github Repo:

 https://github.com/benbahrenburg/benCoding.Android.Tools

Documentation:

https://github.com/benbahrenburg/benCoding.Android.Tools/tree/master/documentation

Example:

https://github.com/benbahrenburg/benCoding.Android.Tools/tree/master/example

iOS Simulator Switching Devices

With Apple’s latest products, including the iPhone 5 we now have to worry about more form factors then ever. As the method for switching the device type in Titanium Studio is still pretty clumsy I went in search of an earlier way.

The Appcelerator forums had a great post by Rob Gabbard with an AppleScript helper to do just what I was looking for. With a small update to add support for the Retina iPad and iPhone 5 I can now switch devices must easier.

I wanted to share a link to this script for anyone that might have missed the QA post. Unfortunately this doesn’t address the need for the app to be launched again when the device is changed.

set selectedDevices to choose from list {"iPhone", "iPhone (Retina 3.5-inch)", "iPhone (Retina 4-inch)", "iPad", "iPad (Retina)"} with prompt "Choose device type:" default items {"iPhone"} without multiple selections allowed
if selectedDevices is not false then
    set selectedDevice to item 1 of selectedDevices as string
    set thePListFolderPath to path to preferences folder from user domain as string
    set thePListPath to thePListFolderPath & "com.apple.iphonesimulator.plist"
    
    tell application "System Events"
        tell property list file thePListPath
            tell contents
                set value of property list item "SimulateDevice" to selectedDevice
            end tell
        end tell
    end tell
end if

View the the gist of the script.

Titanium iOS adding isFile and isDirectory to the SDK

As I was building Dossier.js I ran into a small parity issue between iOS and Android.  On Android Titanium provides you two helper functions.  On a Ti.File object you can call isFile() to get a boolean indicator if your currently working with a file.  Likewise you can call isDirectory() to determine if you are working with a directory.  These are extremely helpful utilities when performing any kind of file system acrobatics.

How do we get this to work on iOS?  Easy, update the SDK and send a pull request.  Just shows how powerful open source can be.

Want to add this to your SDK now?  It couldn’t be easier, just follow the below three simple steps.

Updating your SDK

Find your SDK Directory

The first step is to find your Titanium SDK directory.  This is usually installed under a directory path similar to the one shown below.

path

Adding your methods

After locating your SDK directory, you will need to go to the Classes folder as shown below.

sdkdirectory

Look for the TiFilesystemFileProxy.m file and open this in your favorite text editor.

TiFileSystemProxy

Scroll down in the file until you see the method –(id)createFile:(id)args right above this method paste in the below.

-(id)isFile:(id)unused
{
	BOOL isDirectory;
	return ([fm fileExistsAtPath:path isDirectory:&isDirectory] && !isDirectory);
}

-(id)isDirectory:(id)unused
{
	BOOL isDirectory;
	return ([fm fileExistsAtPath:path isDirectory:&isDirectory] && isDirectory);
}

view on gist

Once completed, save the file (TiFilesystemFileProxy.m)

Clean your project & done

You will need to clean your Titanium Projects before the SDK modifications will be available.  To clean your projects using Titanium Studio go to the Project menu and select Clean… as shown below.

cleanmenu

In the Clean Dialog Window, select Clean All Projects.

cleandialog

You are now ready to use these new functions in your Titanium Projects.

How what? How does it work?

After adding these updates to your SDK, the Ti.File object will have the same isFile and isDirectory methods as they do on Android.  Below is a demonstration app.js you can use for testing.


//Test if the resources folder is a directory.
var resourceDir = Titanium.Filesystem.getFile(Titanium.Filesystem.resourcesDirectory);
Ti.API.info('resourceDir ' + resourceDir);
Ti.API.info('resourceDir nativePath ' + resourceDir.nativePath);
Ti.API.info('resourceDir isDirectory ' + resourceDir.isDirectory());
Ti.API.info('resourceDir isFile ' + resourceDir.isFile());

var newDir = Titanium.Filesystem.getFile(Titanium.Filesystem.applicationDataDirectory,'mydir');
if(!newDir.exists()){
  Ti.API.info("Created mydir: " + newDir.createDirectory());
}

var newFile = Titanium.Filesystem.getFile(newDir.nativePath,'newfile.txt');
newFile.write("\nText appended via write()", true);

Ti.API.info('newdir ' + newDir);
Ti.API.info('newdir nativePath ' + newDir.nativePath);
Ti.API.info('newdir isDirectory ' + newDir.isDirectory());
Ti.API.info('newdir isFile ' + newDir.isFile());

Ti.API.info('newFile ' + newFile);
Ti.API.info('newFile nativePath ' + newFile.nativePath);
Ti.API.info('newFile isDirectory ' + newFile.isDirectory());
Ti.API.info('newFile isFile ' + newFile.isFile());

Ti.API.info('Now open a window so we can test on device easier');

// Create a simple window to show our results
(function(){

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

	win.add(Ti.UI.createLabel({
		top:10, text:'resourceDir isDirectory ' + resourceDir.isDirectory()
	}));

	win.add(Ti.UI.createLabel({
		top:10, text:'resourceDir isFile ' + resourceDir.isFile()
	}));

	win.add(Ti.UI.createLabel({
		top:10, text:'newdir isDirectory ' + newDir.isDirectory()
	}));

	win.add(Ti.UI.createLabel({
		top:10, text:'newdir isFile ' + newDir.isFile()
	}));

	win.add(Ti.UI.createLabel({
		top:10, text:'newFile isDirectory ' + newFile.isDirectory()
	}));

	win.add(Ti.UI.createLabel({
		top:10, text:'newFile isFile ' + newFile.isFile()
	}));

	win.open();

})();

Ti.API.info('End Test');

Titanium Android Module JDT Setup

I’ve just started a project that requires the development of a few Titanium Android modules.  After configuring all of my SDK and NDK paths I was surprised to be greeted with the message that I had to install JDT…

JDT

Since Titanium Studio is Eclipse based the question is what version of the JDT is compatible?  After alittle hunting I found the “Installing the Java Development Tools” guide that provided all of the steps needed to add this dependency.

 

Hopefully this helps someone that is Googling on how to resolve this warning.

Copying or Moving Titanium Folders

Looking for away to Copy or Move a folder in your Titanium app?  Check out Dossier an all JavaScript module that provides a cross-platform API for working with folders.

Where to get it

The Dossier module, example app.js and supporting files are available at https://github.com/benbahrenburg/Dossier

How it works

Dossier is all JavaScript making it simple to both use and modify.  Simply copy the dossier.js CommonJS module into your app and start coding.

Below is a sample app.js showing Dossier in action.

//Create our application namespace
var my = {};
//Import the module
my.dossier = require('dossier');

Ti.API.info('Copy one directory to another');

//Create our source and target directory paths
var sourceDir = Ti.Filesystem.getFile(Ti.Filesystem.resourcesDirectory, 'SampleData');
var targetDir = Ti.Filesystem.getFile(Ti.Filesystem.applicationDataDirectory + '/NewSampleData');

Ti.API.info('Copying ' + sourceDir.nativePath + ' to ' + targetDir.nativePath );
my.dossier.copy(sourceDir.nativePath,targetDir.nativePath);

Ti.API.info('List all the contents of ' + targetDir.nativePath);
var listTargetContents = my.dossier.listContents(targetDir.nativePath);

Ti.API.info('Move ' + sourceDir.nativePath + ' to ' + targetDir.nativePath );
my.dossier.move(sourceDir.nativePath,targetDir.nativePath);

Ti.API.info('List all the contents of ' + targetDir.nativePath);
listTargetContents = my.dossier.listContents(targetDir.nativePath);

Titanium iOS KeyChain support with Securely

I’m happy to announce the the availability of the Securely Titanium module.  The goal of Securely is to provide a security toolkit for Titanium developers to write more secure apps.

KeyChain Properties API

The first release of Securely (iOS only) provides a Properties API which provides access to the iOS KeyChain.  Designed for ease of use the Properties module should be familiar to anyone using Titanium as it mimics the popular Ti.App.Properties API.

var securely = require('bencoding.securely');
Ti.API.info("module is => " + securely);

//You can provide optional identifier and accessGroup 
//If none are provided we will use your bundle id as the identifier
var properties = securely.createProperties({
     identifier:"Foo",
     accessGroup:"Bar"
});

Since the Securely Properties module mimics Ti.App.Properties you simply call setString when you would like to save a value.  Instead of being written to Properties it is instead persisted to the device’s KeyChain.

properties.setString('String','I am a String Value ');

Similarly you use the getString method just like you would for properties, but instead you are retrieving values from the KeyChain.  We even support default values for API compatibility.

Titanium.API.info('String: ' + properties.getString('whatever',"Fred"));

All of your other Ti.App.Properties you rely upon also have a compatible equivalent in Securely.  To see the full list please read our documentation here.

Get the module

The module is available at benahrenburg/Securely on github.

Need an example?

The module’s example folder contains a sample app.js demonstrating all of the available methods.  You can view the sample in on github here.

Learn more

To learn more please visit the Securely github repo and read the documentation.

What’s next?

I am currently working on adding Encryption and File Handling features to Securely.  An Android version is also in the planning stages.

Using the Luhn Algorithm in Titanium

The Luhn algorithm or “mod 10” algorithm, is a checksum used to validate a variety of identification numbers including those used by most credit card vendors.

It was created by IBM scientist Hans Peter Luhn and described in U.S. Patent No. 2,950,048, filed on January 6, 1954, and granted on August 23, 1960.  This is a pretty interesting algorithm as algorithms go and I would recommend checking it out on Wikipedia.

The following demonstrates how you can a CommonJS module implementation of this algorithm in your Titanium app.

Before we can get started, we need to generate a few fake credit card numbers for testing. For this demonstration I used the site “Get Credit Card Numbers”.  This site provided us with the fake number we use in all of our examples.

Credit Card Helper CommonJS Module

First we create our module using the below code.  This module has one function called verifyCardWithLuhn that has one parameter for you to pass in the credit card number you wish to validate.  This function will return true if the provided credit card number is in the correct format, or false if the format is invalid.


exports.verifyCardWithLuhn=function(cardNumber){
  //Remove spaces
	cardNumber = cardNumber.replace(/[^\d]/g, "");
	//Grab our length for use later
	var cardLength = cardNumber.length;
	//If no length return invalid
	if (cardLength === 0){
		return false;
	}
	//Get last digit
    var lastDigit = parseInt(cardNumber.substring((cardLength-1),cardLength),10);
    //Build string with all credit card digits minus the last one
    var cardNumberMinusLastDigit = cardNumber.substring(0,(cardLength-1));
    //Build up our variables needed for our calculation
    var sum = 0, luhnLength = cardNumberMinusLastDigit.length, luhnKey = [0,1,2,3,4,-4,-3,-2,-1,0];

    //Step 1 of our hash add the numbers together
    for (i=0; i<luhnLength; i++ ) {
      sum += parseInt(cardNumberMinusLastDigit.substring(i,i+1),10);
    }
    //Step 2 of our has, we now add in our key values
    for (i=luhnLength-1; i>=0; i-=2 ) {
  	  sum += luhnKey[parseInt(cardNumberMinusLastDigit.substring(i,i+1),10)]
    }

    //Adjust our sum as neeed
   	var mod10 = sum % 10;
   	mod10 = 10 - mod10;
   	if (mod10===10) {
    	mod10=0;
   	}

    //Our hash should now mast the last digit of our number
  	return (mod10===lastDigit);
};

See the gist here.

Calling our Module

Calling our Credit Card Helper module is easy. We simply use the require method to add the CommonJS module into our project.


var my = {tools:{}};
//Import our module into our project
my.tools.cardHelper = require('credit_card_helper');
//Our test credit card number that we got from http://www.getcreditcardnumbers.com/
var testCreditCardNumber ="49713268648235453";
//Call our verify method to check if our credit card number is in a correct format
var ccCheck = my.tools.cardHelper.verifyCardWithLuhn(testCreditCardNumber);
//alert the result back to the user
alert(ccCheck);

See the gist here.

Things to reminder

Please remember this algorithm can only validate if the format is correct.  You will still need to use a 3rd party service to determine if the number itself is active and valid.

Review : Augmented Reality using Appcelerator Titanium Starter

book_reviewOver the holidays I had a chance to read Trevor’s new book “Augmented Reality using Appcelerator Titanium Starter“.   Although I was a technical reviewer this was my first chance to read the completed book cover to cover.

This book is a must have for any Titanium developer looking to explore
Augmented Reality.  If you are just getting started with Titanium this book has a ton of recipes to help get you started.

My favorite section was the discussion on how to handle the views which draw the different location elements.  This is a fresh approach on handling performance issues often related to rapidly moving views.  Just as interesting was the discussions related to the different location algorithms.  Even experienced Titanium developers will find new useful snippets to take away from the author’s code.

If you are new to Titanium development you might want to check out Appcelerator’s Getting Started Guides first, as the author focuses his time on discussing the complexities of the augmentedTi app instead of setup topics.

To learn more about this book please visit the below:

The augmentedTi open source app can be found at the link below:

Creating Keyboard Shortcuts for Switching Tabs in Titanium Studio

I’ve been using Titanium Studio quite a bit lately and noticed the default key mappings for switching tabs was not working for me.  Titanium Studio allows you to easily set your key bindings to anything.

Below are the steps I used to create my tab switching shortcuts.

Where is Key Mapping Preferences?

You can updated Titanium Studio’s key bindings by going to Titanium Studio then selecting the Preferences option as shown below.

PreferencesOption

Titanium Studio provides a large amount of preferences, you can tailor almost anything to your workflow.  The key binds are found under General then Keys.  If you have trouble finding this, just search for “keys” in the filter box.

PreferenceKeyOption

Mapping Next Tab

Once in the Keys option menu, scroll until you see “Next Tab”, you can also filter by “tab” and it will help you find this option.  Select the “Next Tab” as shown in orange below. Then enter “Command Page Up” in the binding section highlighted in blue. Once completed you will need to press the “Apply” button for this option to be immediately available in Titanium Studio.

NextTab

Mapping Previous Tab

Once in the Keys option menu, scroll until you see “Previous Tab”, you can also filter by “tab” and it will help you find this option.  Select the “Previous Tab” as shown in orange below. Then enter “Command Page Down” in the binding section highlighted in blue. Once completed you will need to press the “Apply” button for this option to be immediately available in Titanium Studio.

PreviousTab

Shortcuts in Action…

Now I can switch between tabs just like in my Eclipse projects.

Moving to the Next Tab

Tab1Selected

CMD  jean_victor_balin_add_blue  UAK

Tab2Selected

Moving to Previous Tab

Tab2Selected

CMD  jean_victor_balin_add_blue  DAK

Tab1Selected

Changing a Titanium iOS Module’s GUID

Occasionally you will need to a module’s GUID.  This is commonly done to avoid licensing conflicts with open source modules.

Updating a module’s GUID is a straight forward and simple process.  The below steps demonstrate how to change the GUID in your Titanium iOS custom module.

Before getting started it is important to note that Appcelerator doesn’t support updating your module’s GUIDs so please make a back-up of your original files just in case.

Generate a new GUID

The first step is to generate a new GUID.  I like to use GuidGenerator.com. Using this site we generate a GUID of 2016a336-bc2-494a-b112-98d6edd999de that we will us to update our Xcode module project.

guidgenerator

Updating the Manifest File

When you create a Titanium Module project, a manifest file is automatically created for you.  This file contains your project name, version information, module id, and your module’s GUID.

The manifest file is located in the root of your Xcode project, as shown below.

manifest_file

Open this file in your favorite text editor and change the existing GUID to the new one generated by GuidGenerator.com.  In our case the manifest should now look like the below.

 

manifest_guid_update

Updating your Xcode Project

The next step is to update your module’s moduleId method.  This is located in the <Your Module Name>Module.m file of your project. In this example our module is called BencodingNetwork, so we will want to look in the BencodingNetworkModule.m project file.

finding_class

You will want to open this class file in Xcode and update the moduleGUID property.  You simply update the return value with the same GUID used in updating our manifest file.

xcode_update

Almost done, one last step

Now that you’ve updated your module’s GUID you will need to re-build your module.  To do this open terminal in the root of your module’s folder and run the ./build.py script as shown below.  This will generate a new compile module zip for you to use in your Titanium projects.

termina