Scoutmob and Gmail Insights

January 21st, 2010 Ali Faiz No comments

I hate to follow up Andrew’s post with another “problem” post but I hope this helps some other developers out there who are trying to implement something similar.

Problem Definition

About midway into the first day of scoutmob.com’s going public, we came upon a huge brick wall in the form of Google’s gmail restrictions on emails sent through smtp. Google has a policy (unbeknown to us at the time) that it effectively shuts down emails sent through their smtp server after a user hits 500 emails in one day. We hit this hurdle and subsequently saw error messages to the effect that a quota had been met and our account was no longer valid.

Context

For Scoutmob we implemented a system for them to have users send themselves an email or an sms form of a deal posted on their website. Since we used Ruby/Rails on the backend we simply used the smtp plugin to be able to send emails through their gmail corporate email account.

The smtp plugin used was the ambethia-smtp plugin – for those interested in obtaining it this site was helpful in setting it up. This seemed like the most appropriate option for our purposes, especially since the SMSFu plugin we used for sending sms messages requires an smtp server in order to send sms messages to phone numbers.

Solution

1. Gmail Premium
Our first thought was to buy into Gmail’s premium plan.
Benefits: Quick solution. Gmail’s great product and support for issues.
Drawbacks: Increased costs and the limit for emails sent out of a premium plan account is 2,000. Although this was significantly more than the 500 limit it still was too small for us.

2. Sendmail
Setup sendmail on our servers and use localhost as the smtp server.
Benefits: No limit on number of emails sent. Greater control and less restrictions.
Drawbacks: The onus lies on us to tackle issues when things go wrong. Another possible issue is that since we aren’t a trusted gateway, spam filters, ISP and more importantly, telecoms used for the sms messaging might flag us as malicious emailers.

We decided to use the 2nd option and setup sendmail on our servers. We no longer have to worry about getting shut down by the smtp provider but now there is one more aspect of the site that we must support.

Possible Next Steps

Use Mailchimp’s gem to take care of sending these messages… More to come on that later.

Technorati Tags: , , , , ,

Categories: Uncategorized Tags: , , , , ,

Understanding Views and Windows in Titanium Mobile

December 17th, 2009 Andrew Zuercher 1 comment

Problem Definition

When I’m implementing items in titanium I have an option to create a new view or create a window. It would be good to know what the consequences are for using one vs the other and how an application collaborates across views/windows.

Context

When you implement views or windows in Titanium, you can do so by providing a HTML resource as the parameter to create the corresponding view or window. Titanium in turn creates either:

  • window – a new window with a single webview in it
  • view – adds the view to the window parameter’s stack of views

If you call the titanium window’s open() method with {modal:true}, the new window will be presented modally, IE, coming up from the bottom. This is mostly a behavioral difference, however, as unlike the horizontal push, there is no back button, and it hides the tab bar. This is due to what Apple’s SDK has.

In the beginning, a webView and a window were a single class. As of 0.5 or so, when TableView came about, Window and webView split ways. For backwards compatibility reasons, when you supply an url to a window on creation (Or, technically, all the way up till opening) a nameless webView is created and added. You can even see it or grab it when you use a window’s getViews() method. It’s done on the Objective-C side, but the javascript is the effect of:

1
2
3
4
if(this.url){
  var webView = Ti.UI.createWebView({url:this.url});
  this.addView(webView);
}

Technically speaking, as of 0.8, the only thing that has a context is the web views. Windows may contain web views that have contexts, but windows, tableViews, groupedViews, scrollableViews, imageViews, Buttons, sliders, etc, do not have any javascript context, but instead are controllable by the web views, and thus, that’s why they can see each other is that they’re all in the same web view context.

One thing that does improve performance and flexibility is to move more creation into one context. For example:

file1.html:

1
2
var newWin = Ti.UI.createWindow({url:'file2.html'});
newWin.open();

file2.html:

1
2
3
var table = Ti.UI.createTableView({...});
Ti.UI.currentWindow.addView(table);
Ti.UI.currentWindow.showView(table);

singleFile.html:

1
2
3
4
5
var newWin = Ti.UI.createWindow({});
var table = Ti.UI.createTableView({...});
newWin.addView(table);
newWin.showView(table);
newWin.open();

Using file1.html, you have to generate a new web view (implicitly), wait for it to load, including the rather hefty JS injection, then load in all of data and such before the table shows. Using singleFile, the table is immediately there, even as the animation takes place revealing the new window. The only drawback is that focused events don’t fire on newWin when it should, and a few other bugs that should be addressed.

Going into 0.9, moving more and more code into fewer, more concentrated contexts is the way to get speed, but even now, it can offer some boosts.

Trade offs

It’s important to understand what the trade offs are from one to another

function windows views
multiple animation styles when showing nope (only allow from left or none and from bottom when modal). yip (all sorts of animation styles and parameters provided)
visibility to binded objects in javascript environment nope, objects are not shared across windows yip – depending on the type of view. for example a tableview will have access to the parent window’s javascript objects as explained above
consume/publish to same event manager nope yip events are delivered in the same eventing domain
automatic navigation bar integration yip – you can define the traits for a window when you create it (title, back button title, etc) of course navigation is not shown if the window is opened modally nope, the views share the same fixed navigation for the window they belong to, you can manipulate the nav bar, but this isn’t really the same
coordinate with tabs yip nope

Storing state

If you want to exchange state between 2 windows, then you cannot bind them into a transient javascript object because they are out of scope and do not have visibility to each other’s environment. However, you can make use of Application properties or use a database to persist your state for visibility across windows. When you serialize to/from a string property you can use the JSON representation of the object you are persisting to enable complex objects (this is what we do a lot).

Transitioning between views/windows

In the case where you have 2 views and you want to define interactions you can either:

  • call a method in the javascript environment
  • fire a custom event and consume it in a listener

The above implementations demonstrate a powerful advantage views have over windows, however you can still get around this with window-2-window communication. In either a webview or a window, you can add a listener to the current windows focus event, for example:

1
2
3
Titanium.UI.currentWindow.addEventListener('focused', function() {
  ...
});

Then in the listener you could look for a object stored in the state identified above. In this scenario, one window would store a persistent object when something happens and then when the other window recieves the focus, it would look up this object, notice the state change and perform some behavior.

Wrap up

Understanding the differences between when to use views and when to use windows is important as well as some of the creative work arounds needed to facilitate interactions in your application. We hope you’ve found this useful and encourage you to reach out to us via email if you are in need of any services while building titanium applications.

Categories: Titanium, iphone Tags:

DATA pt. 4 – Running from Command Line and Logging

August 31st, 2009 Ali Faiz No comments

This is part of the continuing series of articles on Developing Appcelerator Titanium Applications (DATA)

Running Titanium Apps from the Command Line

To run a Titanium app using a command line script as opposed to starting it up through the Titanium Developer App, we placed the following in a file named run.sh inside our app’s directory.

export PATH=$PATH:/Library/Application\ Support/Titanium/sdk/osx/0.6.0/
tibuild.py -d . -s /Library/Application\ Support/Titanium -r -a /Library/Application\ Support/Titanium/sdk/osx/0.6.0 ./

The tibuild.py does our work for us and running ./run.sh from the command line starts our app up without having to open the Titanium Developer App.

Logging

This is a short blurb on the difference between Titanium logging and Firebug’s logging. At the top of our Javascript file we have the following try/catch statement to setup our log var.

try {
    var log = Titanium.App.stdout; // Titanium's logging to the command line
} catch (squash) {
    var log = console.log; // console logging for Webkit/Firebug
}

The try/catch is an easy way to ensure we have the right logging for the right environment. We want TItanium logging when running Titanium and console.log as the default.
Calling logging is simple from this point:

 log('HELLO!');

Technorati Tags: , , ,

DATA pt. 3 – File I/O with jQuery and Titanium

August 25th, 2009 Ali Faiz No comments

This is part of the continuing series of articles on Developing Appcelerator Titanium Applications (DATA)

Opening an XML file dialog in Titanium

The props variable specifies that only xml files will be highlighted and accepted in the file dialog. In order to highlight and accept all file types, just make props and empty array: var props = {};

var props = {multiple:false,types:['xml']};
Titanium.UI.openFileChooserDialog(function(filenames) {
	if (filenames[0]){
		Editor.load_file(filenames[0]);
	}
},props);

Reading an XML file

Here are the ways to read an xml (or any) file using both jQuery and Titanium. In both examples, lambda represents a function pointer.

jQuery

	$.get(filename,lambda);

Titanium

	var f = Titanium.Filesystem.getFile(filename);
	var xml = ""+f.read();
	lambda(xml);

Writing an XML file

This of course can only be done with Titanium. Below is how we formatted the xml to pretty print the xml string before writing out to the file. The raw xml string doesn’t lay out nicely so we have to add some spacing.

formatXml: function(xml, lambda) {
    var formatted = '';
    var reg = /(>)(<)(\/*)/g;
    xml = xml.replace(reg, '$1\r\n$2$3');
    var pad = 0;
    jQuery.each(xml.split('\r\n'), function(index, node) {
        var indent = 0;
        if (node.match( /.+<\/\w[^>]*>$/ )) {
            indent = 0;
        } else if (node.match( /^<\/\w/ )) {
            if (pad != 0) {
                pad -= 1;
            }
        } else if (node.match( /^<\w[^>]*[^\/]>.*$/ )) {
            indent = 1;
		} else {
            indent = 0;
		}
 
        var padding = '';
        for (var i = 0; i < pad; i++) {
            padding += '  ';
		}
 
        formatted += padding + node + '\r\n';
        pad += indent;
	});
    lambda(formatted);
},

Below is the code that actually writes out to the filesystem. If the file represented by the filename already exists, the write simply overwrites it. If the file doesn’t exist, a new one with that filename is created. Because of the way we had to parse the xml read in, it was necessary to tack on the the xml header.

try {
	var TFS = Titanium.Filesystem;
	var file = TFS.getFile(filename);
	Editor.formatXml(Editor.currentopenfile.filexml, function(xml) {
		header = '<?xml version="1.0" encoding="UTF-8"?>';
		file.write(header+xml);
		var contents = file.read();
	});
} catch (squash) {
	alert("Failed to write to File");
}

Technorati Tags: , , , ,

DATA pt. 2 – Accessing the DOM with jQuery

August 20th, 2009 Ali Faiz No comments

This is part of the continuing series of articles on Developing Appcelerator Titanium Applications (DATA)

The many ways to access the DOM with jQuery

In part 1 of this series, I ended the post with stating that I would follow up with how we accessed the DOM with jQuery and why we weren’t always using the best way to do it. Given more time, we would likely have gone back and changed all methods of accessing the DOM to be consistent.
Below are 3 ways that we used to access the DOM. It is almost a chronological journey through how we figured out the different methods.
For this part, as I did in my last post, I’ll be using the PushToTest datasource as an example.

Here again is the html used to render a datasource.

<div id="datasources_iterator${id}" class="datasource_container">
	<input type="hidden" name="id" value="${id}" fieldset="datasource"/>
	<table cellpadding="0" cellspacing="0" border="0">
		<tr>
			<td>Name</td>
			<td><input type="text" name="name" value="${name}" fieldset="datasource" class="name"/></td>
			<td><input type="image" name="delete" value="${id}" src="images/cross.png" fieldset="datasource"/></td>
		</tr>
		<tr>
			<td>Type</td>
			<td>
				<select id="datatypeselect${id}" name="datatypeselect" fieldset="datasource">
				  	<option value="HashDPL">HashDPL</option>
				  	<option value="CSVDPL">CSVDPL</option>
				  	<option value="RDBMSDPL">RDBMSDPL</option>
				  	<option value="TheLocker">TheLocker</option>
				</select>
			</td>
		</tr>
		<tr>
			<td>Resource Name</td>
			<td><select id="rscname${id}" datasourceid="${id}" name="rscname" fieldset="datasource"></select> (From Resources)</td>
		</tr>
	</table>
</div>

The Unique ID Approach

The simplest way to manipulate the DOM with jQuery is using the id based method.
In the html we have datatypeselect drop down menus.

<select id="datatypeselect${id}" name="datatypeselect" fieldset="datasource">
  	<option value="HashDPL">HashDPL</option>
  	<option value="CSVDPL">CSVDPL</option>
  	<option value="RDBMSDPL">RDBMSDPL</option>
  	<option value="TheLocker">TheLocker</option>
</select>

For each individual datasource displayed, there is a datatypeselect drop down with a unique id associated with that element.
Here is the javascript to set the value of the datatypeselect for a given datasource object. This follows the method for populating the html we covered in part 1 of this series.

$("#datatypeselect"+datasource.id).val(datasource.datatypeselect);

The ‘#’ at the beginning of the selector signifies that we’re selecting based on the id attribute of the html element. The value is being set to the datasource object’s datatypeselect field.

The div ID Approach

This approach is similar to the Unique ID Approach, but instead of using the id for the particular element, we can use the id for a parent of this element. This forces us to only have a unique id at the parent level instead of a unique id for each individual html element.

The parent of the datatypeselect element in the html:

<div id="datasources_iterator${id}" class="datasource_container">

Here’s the javascript for this approach to accessing the datatypeselect element:

var divid = '#datasources_iterator'+datasource.id;
$(divid+ ' select[name=datatypeselect]').val(datasource.datatypeselect);

The Parent Selector Approach

This approach uses the same divid as the div ID Approach above but we pass the selector as an argument. Here we also use the fieldset attribute to give greater specificity to the jQuery selector.

$('select[name=datatypeselect][fieldset=datasource]', $(divid)).val(datasource.datatypeselect);

Ultimately we want to strip our html elements to the bare minimum of what we really need to access and manipulate their values and get away from using unique ids for each element.

Technorati Tags: , , , ,

Developing Appcelerator Titanium Application (DATA) pt. 1 – A series of articles on lessons learned…

August 20th, 2009 Ali Faiz No comments

The Application: PushToTest TestMaker

As part of our work on the PushToTest TestMaker open source project, we ran into numerous issues and resolutions that we felt should be shared.

Some background on what we used:
- Appcelerator Titanium Developer
- Javascript
- jQuery 1.3.2
- jQuery template plugin
- jQuery scrollTo plugin
- ExtJS 3.0 rc 3

First Issue To Address

One of the key first issues we ran into was how to render the html using jQuery on the client side for the Titanium application without doing too much manual DOM manipulation. Also, since most of the information being rendered would be in arrays, it would preferably make displaying arrays easier.

The Solution

Our solution came in the form of the jQuery template plugin.
For our implementation, we created html code snippets that we placed in individual html files. Each html file would be loaded and be passed into the $.template method which would then be passed into a .append method along with an object whose values would be injected into the html.

The reason why templating and more specifically why breaking the html into snippets was necessary is almost entirely because we wanted to be able to iterate through multiple objects and display them the cleanest and most efficient way possible.

Example with the PushToTest Datasource

For an example I’ve lain out how we rendered the information for datasources. Datasources are objects that have names, types, and resource names.
First we created a datasources.hmtl page that will be a container for all the datasources rendered:

<div class="panelmessage">
Make this a data-driven test.
</div>
 
<div class="form">
	<div class="title">
		Data Production Libraries (DPLs) provide operational test data to the tests as they operate. For example, a DPL reads data from a relational database, comma-separated-value (CSV) file, or data generating object and injects it into a test script. <a id="ShowTutorials" name="ShowTutorials" class="link">Read more about it.</a>
	</div>
	<div id="datasources_iterator" style="display:none" class="">
	</div>
	<div class="adddatasource">
		<a id="adddatasource" name="adddatasource" class="link" dirty="true">Add DPL</a>
	</div>
</div>

Then, we created a _datasourcestemplate.html file with all the attributes for a datasource specified:

<div id="datasources_iterator${id}" class="datasource_container">
	<input type="hidden" name="id" value="${id}" fieldset="datasource"/>
	<table cellpadding="0" cellspacing="0" border="0">
		<tr>
			<td>Name</td>
			<td><input type="text" name="name" value="${name}" fieldset="datasource" class="name"/></td>
			<td><input type="image" name="delete" value="${id}" src="images/cross.png" fieldset="datasource"/></td>
		</tr>
		<tr>
			<td>Type</td>
			<td>
				<select id="datatypeselect${id}" name="datatypeselect" fieldset="datasource">
				  	<option value="HashDPL">HashDPL</option>
				  	<option value="CSVDPL">CSVDPL</option>
				  	<option value="RDBMSDPL">RDBMSDPL</option>
				  	<option value="TheLocker">TheLocker</option>
				</select>
			</td>
		</tr>
		<tr>
			<td>Resource Name</td>
			<td><select id="rscname${id}" datasourceid="${id}" name="rscname" fieldset="datasource"></select> (From Resources)</td>
		</tr>
	</table>
</div>

Then in the javascript we use this code to get that content and template it:

	$.get('content/_datasourcestemplate.html', function(html) {
        Editor.datasourcesTemplate = $.template(html);
    });
 
	for (var i=0;i<Editor.currentopenfile.datasources.length;i++) {
		var datasource = Editor.currentopenfile.datasources[i];
		$('#datasources_iterator').append(Editor.datasourcesTemplate, datasource);
	}

Using this method we were able to iterate through the datasource objects and inject them into the template, then append it to the datasources.html page.

Post implementation lessons

As you can see in the _datasourcestemplate.html code, we placed the datasource object’s id all over the place. Originally this was needed because of the way we were using jQuery to get values from the DOM. After doing some more research we found out better ways to gain access to the DOM which is what I will cover in the next post.

Technorati Tags: , , , ,

andrewzuercher.com – personal blog site migrated

July 6th, 2009 Andrew Zuercher No comments

Greetings,

We’ve migrated off andrew zuercher’s personal blog site to http://andrewzuercher.com. Going forward, this site (http://blog.zuerchtech.com) will only include posts that are company specific and not of a personal nature.
Categories: Uncategorized Tags:

Barcamp 2008

October 29th, 2008 Andrew Zuercher No comments

Finally a week after barcamp altanta 2008 I have a second to write about the weekend – its been a crazy past few weeks for me. Barcamp was great, same as last year, but this time i knew a few more of the attendees (its a small world). Some of the highlights for me

  • jedi mind tricks – reciprocity, commitment & consistency, social proof, authority, scarcity, reactities, liking, contacts, and co-operation. Dont you think that those are some very keen tactics? answer “those are some very keen tactics.
  • an open source talk
  • a political discussion – i caught the end of it
  • a preso on fluid
  • iphone sdk 101
  • and my favorite poker till 4am – honed up my skills in omaha and texas hold-em

While there i presented a session on Appcelerator and TestMonkey. It was a great weekend and I really like our atlanta community and glad to see it unite for a weekend. Looking forward to atlanta startup weekend 2 here in a few weeks.

Technorati Tags:

Categories: barcamp Tags:

No Fluff Just Stuff Atlanta Fall 2008

October 29th, 2008 Andrew Zuercher No comments

Friday through Sunday this week I attended no fluff just stuff in atlanta. Some of you may have seen some of my tweets. Some of the key sessions that I attended and really enjoyed:

  • Groovy by Scott Davis. Scott has a tremendous amount of energy and did a very good job of covering some of the lesser known aspects of groovy as well as grails
  • GWT by David Geary. David is local to Atlanta and provided some humor while explaining the internals of GWT
  • Agile and Architecture by David Hussman. David is an agile coach and had a very open and interactive session that was very enjoyable
  • Cloud Computing by Michael Nygard – helped answer a lot of my questions with practical examples. He knows his stuff and I cant wait to start using AWS on some of my upcoming projects.

While at the conference I ended up tweeting with some of the other attendees. That was pretty cool. It was a very long weekend and made for a tiring Monday, but I’m glad that I had the opportunity to attend the sessions.

Technorati Tags:

Categories: nfjs Tags:

Zuercher Technologies Re-born

October 29th, 2008 Andrew Zuercher No comments

Zuercher Technologies is making a comeback. As many of you probably already know the Appcelerator Atlanta Office closed down. Some have asked me what is on the horizon and I’ve held back a little to make a formal announcement. Over the next couple of weeks I’ll be putting up a new web front for zuerchtech, but the premise is that I will be starting a services delivery company aimed at helping companies create RIA based web solutions as an Appcelerator partner. I’d like to thank all those who have offered their support over the past couple of weeks and am very excited with the opportunities to come in the near future!

Categories: announcements Tags: