Appcelerator Developer Blog

Newbie Tuesday: WebView with remote HTML

The following is the latest entry in a series of Tuesday blog posts covering basic topics in Titanium and JavaScript development.

A common need in Titanium applications is to display the content of a remote web page inside a web view. Maybe it’s a blog post linked to in an RSS feed or your own website – in any event, you often need to embed that content directly in your app, rather than launching a web page in the device’s browser.

In order to do this effectively, you should be sure to give the user feedback as the remote site is loading, so they know your app is doing something. This is especially important for web pages that are not mobile optimized, and tend to load up slowly over a mobile data network. How you create this UI will vary greatly depending on the nature of your app, but the events you’ll listen for on the web view will be the same. The web view has lifecycle events that will clue you in to the current progress of a web page as it loads.

Let’s create a simple application with a web view that will load the url given to it in a text field:

var w = Ti.UI.createWindow({
	backgroundColor:'white'
});
 
var form = Ti.UI.createView({
	height:60,
	top:0,
	backgroundColor:'#787878'
});
w.add(form);
 
var urlField = Ti.UI.createTextField({
	value:'http://www.cnn.com',
	top:5,
	left:5,
	right:120,
	bottom:5,
	borderStyle:Ti.UI.INPUT_BORDERSTYLE_ROUNDED
});
form.add(urlField);
 
var btn = Ti.UI.createButton({
	width:110,
	right:5,
	top:5,
	bottom:5,
	title:'Go'
});
form.add(btn);
 
var webView = Ti.UI.createWebView({
	url:'http://www.cnn.com',
	top:60
});
w.add(webView);
 
w.open();

Which will look like this on iOS and Android:

Now, let’s expand that application with a modal loading state we’d like to display as the page loads by adding an opaque view to the main window:

var overlay = Ti.UI.createView({
	backgroundColor:'#cdcdcd',
	opacity:0.75
});
overlay.add(Ti.UI.createLabel({
	height:'auto',
	width:'auto',
	text:'Loading...',
	color:'#787878',
	font: {
		fontSize:24,
		fontWeight:'bold'
	}
}));
w.add(overlay);

Which should look like:

Next, let’s add some logic around the button click and the web view’s “load” event to toggle the overlay.

btn.addEventListener('click', function() {
	urlField.blur();
	webView.url = urlField.value;
	overlay.show();
});
 
webView.addEventListener('load', function() {
	overlay.hide();
});

Our little web browser is now complete! Drop this complete sample in app.js to see it in action:

var w = Ti.UI.createWindow({
	backgroundColor:'white'
});
 
var form = Ti.UI.createView({
	height:60,
	top:0,
	backgroundColor:'#787878'
});
w.add(form);
 
var urlField = Ti.UI.createTextField({
	value:'http://www.cnn.com',
	top:5,
	left:5,
	right:120,
	bottom:5,
	borderStyle:Ti.UI.INPUT_BORDERSTYLE_ROUNDED
});
form.add(urlField);
 
var btn = Ti.UI.createButton({
	width:110,
	right:5,
	top:5,
	bottom:5,
	title:'Go'
});
form.add(btn);
 
var webView = Ti.UI.createWebView({
	url:'http://www.cnn.com',
	top:60
});
w.add(webView);
 
var overlay = Ti.UI.createView({
	backgroundColor:'#cdcdcd',
	opacity:0.75
});
overlay.add(Ti.UI.createLabel({
	height:'auto',
	width:'auto',
	text:'Loading...',
	color:'#787878',
	font: {
		fontSize:24,
		fontWeight:'bold'
	}
}));
w.add(overlay);
 
btn.addEventListener('click', function() {
	urlField.blur();
	webView.url = urlField.value;
	overlay.show();
});
 
webView.addEventListener('load', function() {
	overlay.hide();
});
 
w.open();

Hope that helps!


Featured Developer – Ben Bahrenburg

Editor’s note: Sharry Stowell is the editor of Learning Titanium, where he frequently comments on the latest contributions of the Titanium community.

Over the previous few months I’ve noticed a few developers in the Titanium community shine brighter and brighter. They’ve helped out on the Q&A forum, answered questions over IRC, shared the latest Titanium news and even created modules for the Appcelerator MarketPlace for all to use and enjoy. The Titanium developer of the week has to go to Ben Bahrenburg for his outstanding contribution to the community.

Ben has over 14 years experience in systems, software and module development. Starting out as a Oracle DBA, then moved onto focus on DSL base high volume payroll transactions for PriceWaterhouseCoopers.

Interview with Ben Bahrenburg

A few weeks ago I had an interview with Ben and asked him a few question about Titanium, here is what he said:

How did you get involved in Titanium development?

I found Titanium about three years ago through Twitter. After a couple of weekends experimenting with the API, I was hooked. It was impressive even back then how quickly you could build apps.

Do you have any Apps created in Titanium?

Like most Titanium developers I’ve created a ton of apps over the years. The two most notable are Aidori an app to help with the Japan 2011 Earthquake, and bARk an open source augmented reality app that was used in a session at last year’s CodeStrong conference.

A majority of the apps and frameworks I’ve created are for my employer. The most notable of these is the myTravel app which is featured in a recent Appcelerator case study.

How are you involved in the Titanium Community?

There has always been a great community around Titanium. Back in the 0.4 days Jeff and Nolan would answer most support questions themselves. In this spirit I help out in the Q&A forums, on community project, and over Twitter as much as possible.

Whenever I run into an interesting problem in the QA forum or on my own projects I create tutorials on my blog bencoding.com or post samples to github.

The Titanium Titan program has provided the chance to talk about Titanium at several hackathons and user groups. This has been a great opportunity to code and learn from the Titanium community. It has become a personal mission of mine to pair program with as much of the Titanium community as possible. This has been a great way to both learn and give back.

Do you have any experience in Titanium Module creation?

I’ve created a few commonJS format modules.

TiTaffyDb – A Titanium port of the populator NoSQL JavaScript database
Soup – A framework for working with Geo Location based content providers
Atlas – A Geo Location framework, that allows for chaining, provider rating, and fallbacks.

The Titanium module architecture make is relatively easy to plugin native modules. I have a few native iOS modules I hope to make available once iOS 5.1 ships.

What’s your favorite platform to develop in? Any plans to expand?

I enjoy the challenge of building for tablets. Until just recently that meant the iPad but now with the Kindle Fire and Windows 8 Metro it is starting to be more exciting from a cross platform point of view.

Over the last month I have been experimenting to see how much code re-use I can achieve using Titanium on the Kindle Fire and WinJS on Windows 8. So far the results have been limited but encouraging. From a Titanium devs point of view WinJS feels similar and provides a great level of skill reuse.

Modules

Since taking part the interview, Ben has been busy trying a new challenge – to release a module each Monday for a month! So far he has created 3 great modules, with a few more to come too:

NETWORK HELPERS MODULE

TiNetworkHelpers is a module that provides support for Carrier information, SSID, BSSID, and Apple’s Reachability utility class. Its currently only available on iOS, with Android support coming shortly:

1. CarrierInfo – Provides access to the native CTTelephonyNetworkInfo framework object

  • carrierName – Provides access to the carrier name associated with the device’s SIM.
  • mobileCountryCode – Provides access to the carrier Mobile Country Codes (MCCs). This is the country code associated with the carrier on the SIM
  • mobileNetworkCode – Provides access to the carrier’s Mobile Network Code. This is the network code associated with the carrier on the SIM
  • isoCountryCode – The ISO country code for the user’s cellular service provider. This is the carrier on the SIM
  • allowsVOIP – Indicates if the carrier allows VoIP calls to be made on its network

CarrierInfo

2. CurrentNetwork – Provides access to the native CNCopyCurrentNetworkInfo object

  • SSID – Provides access the SSID the device is currently connected
  • BSSID – Provides access the BSSID the device is currently connected

CurrentNetwork

3. Reachability – Provides a wrapper for the Apple Reachability module

  • reachabilityForLocalWiFi – This method provides a boolean result if Local Wifi is enabled
  • reachabilityWithHostName – This method takes a host name, such as www.appcelerator.com and returns a boolean result if the host is reachable
  • hostNameReachableBy – This method takes a host name, such as www.appcelerator.com and returns a constant with how it is reachable

Reachability
Useful links: BLOG POST | CODE | MARKETPLACE


TITANIUM DICTIONARY MODULE

What to use the native iOS5 Dictionary in your Titanium Mobile app? The new benCoding.Dictionary module that makes it easy to this functionality into any Titanium app that targets iOS5 or greater.

Dictionary module

Useful links: BLOG POST | CODE | MARKETPLACE


TITANIUM SMS MODULE

The benCoding.SMS module makes it easy to add SMS functionality into your iOS Titanium apps. We unleash the power of Apple’s native Apple SMS component to Titanium with an API fashioned after the Titanium EmailDialog to make it familiar to use.

SMS module

Useful links: BLOG POST | CODE | MARKETPLACE


As you can see from above, Ben has been extra busy! Please remember all these modules are FREE to use and are available within the Appcelerator Marketplace.

If you have have developed an App in Titanium, a module for Titanium or just have some news you wish to share with the community please head on over to LearningTitanium.com or follow me on Twitter here.

Code strong!

— Tags:

Win up to $5K hacking Titanium apps with Box

Titanium developers have a great opportunity to score up to $5000 cash money in two developer challenges, sponsored by Box. The first is a challenge open only to Titanium developers, offering up to $1250 in prize money for the best Titanium apps making use of the new, open source Box CommonJS module.

Sign up here for the Titanium-only Box developer contest.

Box is also putting out a call for the best iPad application – native or otherwise – utilizing the Box APIs. We have a feeling a Titanium app could win this one as well :).

Sign up here for the iPad Box developer contest.

To help bootstrap your Box development knowledge, please check out this week’s episode of Forging Titanium, which covers the usage of the new Box module. Good luck, and we can’t wait to see what you come up with!


SQL Encryption and Full-Text Indexing with Titanium Mobile

Editor’s note: This is a guest post from community member and contributor Mark Burggraf, on his latest addition to the module marketplace. Would you like to contribute a guest post? E-Mail us at community@appcelerator.com to let us know!

Our new custom module for Titanium, “SQL Encryption and Full-Text Indexing” allows you to create and maintain AES encrypted databases in your applications using SQLCipher technology.  To quote from the SQLCipher web site: “SQLCipher is an SQLite extension that provides transparent 256-bit AES encryption of database files. Pages are encrypted before being written to disk and are decrypted when read back. Due to the small footprint and great performance it’s ideal for protecting embedded application databases and is well suited for mobile development.”

Let’s build a mobile project in Titanium for Android that uses encryption and full-text indexing.

Step 1: Create your empty project.  We’ll assume here that you have Titanium Studio running, with Titanium Mobile SDK 1.8.1, and the Android SDK already installed and configured.  We called our project “SQLEncryption”.

Step 2: Copy the module zip file into the root of your project.  The module zip file should be named:  com.dmarie.sql-android-2.1.zip.

Add zip file to project

Add zip file to project

Step 3: Run your project in the Android emulator.  The first time you run your project, you’ll see the zip file disappear from the root of your project.  Titanium Studio will unzip the module and place it in /modules/android/com.dmarie.sql/2.1, as seen here:

Expanded Module

Module is expanded into the project

Step 4: Add a module reference to your tiapp.xml line.  Open your tiapp.xml file in Titanium Studio, click the “tiapp.xml” tab to edit the xml version of the file, then scroll to the bottom of the file.
Remove the line:

<modules/>

And replace it with these lines:

<modules>
    <module version="2.1">com.dmarie.sql</module> 
</modules>

Step 5: Copy the CommonJS module “db.js” from the /modules/android/com.dmarie.sql/2.1/example folder to your /Resources folder.  This CommonJS module makes it much easier to use our encryption module, and it also provides compatibility with most existing SQLite code you may have already written.

Step 6: Edit your app.js file.
Remove all the contents and replace it with the following 6 lines — (we’re just going to make a simple scrolling screen here):

var win1 = Titanium.UI.createWindow({backgroundColor:'#fff'});
var scrollView = Titanium.UI.createScrollView({});
var label = Titanium.UI.createLabel({ color:"black"  });
scrollView.add(label);
win1.add(scrollView);
win1.open();

Now we can simply say:

label.text += "add text here\n";

when we want to write entries to our scrolling screen.

Step 7: Add a reference to our CommonJS module db.js:

var db = require("db");

Step 8: Open an encrypted database, create a table, and add data to it:

label.text += "databases will be stored here: " + db.dbPath + "\n";
label.text += "open encrypted.db, create a table, then add a record...\n";
var maindb = db.openDB("encrypted.db", "my secret password");
maindb.execute("create table if not exists people (name TEXT)");
maindb.execute("insert into people (name) values ('John Smith')");
maindb.execute("insert into people (name) values ('John Adams')");
maindb.execute("insert into people (name) values ('Peter Tork')");

Some things to note here –

  • If the file “encrypted.db” does not exist, it will be created automatically.
  • Databases will be created and opened in the folder specified by db.dbPath.  (You can set this to any folder you like inside db.js.)
  • If you want to distribute a database with your application, you’ll need to manually copy it to the folder specified by db.dbPath before you can use it.  There is no equivalent to the Titanium.Database.install command, so installing your data file is up to you.
  • The second parameter of db.openDB accepts one of three things:
    • “” (an empty string) – this will create an unencrypted, normal SQLite database
    • “DEFAULT” – if you send the literal word DEFAULT, the password used will be the value returned by Titanium.App.guid
    • “any password you choose” – anything else you send will be considered a password (encryption key) for the database
It’s important to note that your data is never going to be 100% secure as long as the encryption key you’re using is stored in a place where a potential hacker has easy access to it.  In our example here, it may be easy for a hacker to locate “my secret password” by perusing  your application files.  If security is very important to you, you’ll need to find some other safe way to store your key.  Here are some suggestions:
  • Use a complex key created by manipulating text from multiple sources, adding salt, doing bitwise manipulation, etc.
  • Hide the key by using a sequence of bytes stored in a binary file that’s already included with your application.  You can read your binary file into a buffer and extract out a per-determined sequence of bytes that either comprises your key, or just a portion of your key.
  • Don’t store the key with your application at all — instead open an ssl data connection to your secure server and get the key over the network at runtime.

There are many ways to secure your key (if that’s important to you) but that task is up to you.

Step 9: Open a cursor and extract some data:

label.text += "open a cursor and extract some data:\n";
var rows = maindb.execute("select name from people");
label.text += rows.length + " rows were found:\n";
while (rows.isValidRow())
{    
    label.text += "name: " + rows.fieldByName("name") + "\n";
    rows.next();
}

Step 10: Create a full-text index using FTS3 (see http://www.sqlite.org/fts3.html):

maindb.execute("create virtual table FT USING fts3(name TEXT)");
maindb.execute("insert into FT (rowid,name) select rowid,name from people");

Step 11: Query the full-text index and print some results:

label.text += "testing full-text index:\n";
var srch = maindb.execute("select name,rowid from FT where name match 'john'"); // uses FTS3 index for speed
while (srch.isValidRow())
{
    label.text += srch.fieldByName("name") + " found at rowid " + srch.fieldByName("rowid") + "\n";
    srch.next();       
}

Let’s look at the database now and see if it’s really encrypted.  To compare our encrypted database to a regular, un-encrypted version, let’s run this app twice.  We’ll create two databases, an un-encrypted version and an encrypted version.

First, let’s change the location of our databases to something easier to find.  Find the openDB line of code and change it to:

db.dbPath = "/sdcard/"; // this will put databases in the root of the sdcard
var maindb = db.openDB("unencrypted.db", "");

Now run the app. This should create an unencrypted database in the root of your sdcard.

Now change the openDB line to this and run the app again:

var maindb = db.openDB("encrypted.db", "foo");

Let’s see the results of our work.  Open a terminal session (assuming you’re running OSX here) and pull the databases off your sdcard image so we can look at them:

$ adb -e pull /sdcard/unencrypted.db .
$ adb -e pull /sdcard/encrypted.db .

You’ll need to have the Android adb tool on your path.  If it’s not on your path, you’ll have to specify a full path to adb.  At this point, you should have two files in your current folder named encrypted.db and unencrypted.db.

Try opening the unencrypted version with sqlite3:

$ sqlite3 unencrypted.db
SQLite version 3.6.21
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .tables
people
sqlite> .exit

So we can see the “people” table just fine — no encryption here!  Let’s do the same with the encrypted database:

$ sqlite3 encrypted.db
SQLite version 3.6.21
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .tables
Error: file is encrypted or is not a database
sqlite> .exit

This database is encrypted alright.  Let’s do a hexdump and prove that it’s encrypted:

$ hexdump -C unencrypted.db

Looking at the output, it’s easy to see our data:

Hex dump of unencrypted database

Hex dump of unencrypted database

Let’s do the same with the encrypted file:

$ hexdump -C encrypted.db

You’ll just see a long stream of encrypted bytes here:

Hex dump of encrypted database

Hex dump of encrypted database


Appcelerator acquires Cocoafish

Today, we announced that Appcelerator has acquired Cocoafish, a cloud services company which provides a variety of very useful services to mobile (or any) clients through a simple REST API, with no server-side code. To learn more about Cocoafish, check out their website. For more information on how Cocoafish fits into the family here at Appcelerator, you can check out our official info page here.

What does this mean for developers?

Appcelerator aims to deliver a fully integrated mobile development platform. By bringing Cocoafish into the fold and tightly integrating its (already very cool) cloud services and REST API, we hope to make it really easy to build mobile apps with back end data services for persistence, notifications, social features, and more. Look for built in support in the Titanium JavaScript API for Cocoafish persistence services very soon.

Attend the webinar!

Also, make sure to join us next Thursday for a webinar with the Cocoafish team, where we’ll answer questions on the acquisition and do some demos of how these persistence services work within a Titanium application today.

Page 30 of 90« First...1020...2829303132...405060...Last »