FlairLoc Public Beta

FlairLoc is an Adobe® AIR™ application to localize Adobe® Flex® applications.

Today I am happy to announce that the public beta of FlairLoc is available.

Features

  • Change resources in a user interface with search capability
  • Extract resource keys from source code and synchronizes it with all locale sets
  • Automatic translation into 42 languages with the Google Translate API
  • Add new automatic translated languages in only 4 CLICKS
  • Generation of locale compile statement and Ant parameters

For more information, screenvideo and screenshots and to install the application please visit the product page.

GIT Tips and Tools

If you don’t know GIT yet it is a software version control system like Subversion, CVS or Perforce. It was primary developed by Linus Torvalds for Linux kernel development.  I have started using GIT in the beginning of 2009 and I must say that after a not so small learning curve I really like it and see all the benefits especially when it comes to collaboration.

There are alternatives but GitHub is currently the best service to use GIT. You can host open source projects for free and the pricing for private projects is not too expensive. Check out my GitHub profile with my open source projects here.

To get started you should first install GIT on your machine and read the docs.

The tooling support around GIT is perhaps not as extensive like for other VCS yet, so if you are afraid of using the console GIT might not be right for you. However, there are already great tools around but for many things I am still using the Terminal.

Custom Bash Prompt

I am using a custom bash prompt which indicates on which branch you are and further color highlighting helps to keep track:

Terminal — bash — 140×50
Uploaded with plasq’s Skitch!

Eclipse Plugin

My main IDE is Eclipse with Flash Builder or FDT so the Eclipse EGIT plugin is really a must have:

Flash - Eclipse - /Users/soenkerohde/Documents/workspace_gumbo
Uploaded with plasq’s Skitch!

Merge Tool

Merging is an important task when working in a team. GIT is really flexible and you can configure it to use 3rd party apps for merging. I am not a big Perforce fan but the free p4merge tool is really great. Check out the blog post by Andy McIntosh for a detailed explanation how to set it up.

GitX

GitX is maybe the best tool to visualize the branch history but I must say that I don’t use it in my daily work. It can also be used to create commits and revert changes etc.

Links

Commands

If you are new to GIT it is hard to remember all the different commands. Here a list of commands which I use very often also as a reference for me ;)

Create a local repository:

# clone an existing repository
git clone [GITHUB_CLONE_URL]
 
# or do it the long way:
mkdir [PROJECT_DIR]
cd [PROJECT_DIR]
git init
touch README
git add README
git commit -m 'first commit'
git remote add origin [GITHUB_CLONE_URL]
git push origin master

Changes and Commits:

# To see which files are changed and maybe not added yet to the repository use
git status
# Add a file to the repository
git add [FILE]
# or to add all untracked files
git add .
 
# revert a change
git checkout -- [FILE]
 
# when you are ready with a change
git commit -am "[CHANGE_DESCRIPTION]"
# a commit is only local so when you want to push it to the server
git push origin [REMOTE_BRANCH_NAME]

Branches:

# Create remote branch
git push origin master:[REMOTE_BRANCH_NAME]
# Checkout and track remote branch
git checkout --track -b [LOCAL_BRANCH_NAME] origin/[REMOTE_BRANCH_NAME]
 
# local branch list
git branch -l
# remote branch list
git branch -r

Tags: Every time you make a release or reach a milestone creating a tag is a good idea.

# Create tag
git tag -a [TAG_NAME] -m "[TAG_DESCRIPTION]"
# Push tag
git push --tags origin master

Merge: You should work on a branch when implementing a new feature or story. If you are done you should merge this into the main branch.

# Switch to feature/story branch
git checkout [STORY_BRANCH]
# make changes and when done
git commit -am "[DESCRIPTION]"
# switch to master
git checkout master
# get all changes from master
git pull
# switch to story branch
git checkout [STORY_BRANCH]
# rebase story branch with master changes
git rebase master
# maybe solve conflicts
git mergetool
# switch back to master
git checkout master
# finally we can merge it in and there should be no conflict
git merge [STORY_BRANCH]
git push

Stash: When you have changes in your working directory and want to switch to another branch you can stash your changes.

# Create stash
git stash
# Apply
git stash apply

When you migrate a project from SVN to GIT this comes in handy:

find . -name .svn -print0 | xargs -0 rm -rf

btw: GIT has only one .git directory and not one for every directory like SVN

If you have some commands which are important on a daily base please drop a comment so I can extend this post.

YouTube AS3 example

Today YouTube finally released an ActionScript 3 API. Maybe this was accelerated by the move of Vimeo because they came up with an AS3 API last week.

I have build a little AIR client as an example application. Check my YouTubeAS3 project on github for the source code. The example of course uses the Swiz framework.

The meat is the Player class and the IPlayer interface which wraps the YouTube proxy object. The Player extends UIComponent and implements IVisualElement so it works decent with Flex 4. The original SWFProxy object extends Sprite which is fine for Flash but not for Flex.

If you are to lazy to study the API docs like me this screenshot might help:

Flash Debug - Eclipse - /Users/soenkerohde/Documents/workspace_gumbo
Uploaded with plasq’s Skitch!

The example is still pretty small but I’ll try to extend it when I find some time in the future.

Presentation Model Interface with Swiz

Lately I have started to use the presentation model approach and I like it a lot. Swiz fellow Ben Clinkinbeard has a wonderful example posted on his blog.

However I disliked that I have to dispatch custom events to make getters bindable. This would normally look like this in an interface:

[Bindable(event="customDataChanged")]
function get someData():Array;

The problem with it is that I have to dispatch an event typed “customDataChanged” from the presentation model implementation when I want the binding to be updated.
So my implementation would look like this:

private var _someData:Array;
public function get someData():Array{
    return _someData;
}
 
public function setSomeData(a:Array):void{
    _someData = a;
    dispatchEvent(new Event("customDataChanged"));
}

But what I wanted to use is the Swiz autowire-by-property style which would look like this:

[Bindable]
[Autowire(bean="appModel", property="someData")]
public var someData:Array

So for the examle above I have a bean with id appModel defined in my IoC Container (BeanLoader) which contains the someData variable. Swiz wires the property into the presentation model implementation but how do I get my interface getter bindable?
The solution is quite easy. Just have a look at the generated actionscript with the compiler args -keep-generated-actionscript and you see that by default a PropertyChangeEvent is dispatched for bindable variables when they are changed. The type value of the event is “propertyChange” so the only thing I have to change in my interface is the event type:

[Bindable(event="propertyChange")]
function get someData():Array;

So my view gets the presentation model interface autowired-by-type:

[Bindable]
[Autowire]
public var model:IMyPresentationModel;
<s:List dataProvider="{model.someData}"/>

Now when the application model someData property changes, Swiz updates the autowired property which fires a PropertyChangeEvent and forces the binding to be updated in the view.

High level AS3/Flex library for OAuth with Twitter from AIR

Recently I have played again with the Twitter API and finally have OAuth working. When I have first played with the Twitter API I have used the example from Tour de Flex. The example loads up the friends list and uses the Twitter AS3 API. The API is not really my taste but offers the functionality to build a Twitter client application. However when you want to have your client application to show up as the source of tweets you have to use OAuth for user authentication. It adds another step to get started but is a good decision to force developers to use OAuth which should provide more trust into the client app because users don’t like to enter their Twitter credentials into a 3rd party application.

After a bit of research a came across the awesome open source library oauth-as3. There were no examples yet but I remembered an Email from my friend Claus with a link to this github project. The example application uses the oauth-as3 library and demonstrates how to integrate the library.

To use OAuth in your Twitter application you need a consumerKey and consumerSecret which you can get after the registration of your client app: http://twitter.com/oauth_clients/ or go to your settings and select the “Connections” tab for an overview and further links.
However, the github example doesn’t work anymore because Twitter changed their API recently and implemented a PIN mechanism for desktop cients which should provide even more security.

So how does it work?

  1. Get the request token with your consumerKey/Secret
  2. Open the browser and pass the request token
  3. User authenticates on the Twitter site and gets a 6 digit pin code
  4. User enters pin code in the AIR app which you need to get the access token
  5. Save the accessKey/Secret in the EncryptedLocaleStorage for all further requests/sessions

I have build a high level AS3/Flex library for OAuth which is hosted on github. The library is licensed under Apache License, Version 2.0.
Check the inline comments of the IOAuth interface which should already explain the basics.

Here a little semi pseudo code example:

// create OAuth
oauth:IOAuth = new OAUth(consumerKey, consumerSecret);
 
// get request token
var loader:URLLoader = oauth.getRequestToken("http://twitter.com/oauth/request_token");
loader.addEventListener(Event.COMPLETE, requestTokenHandler);
 
function requestTokenHandler(e:Event):void
{
	requestToken = OAuthUtil.getTokenFromResponse(e.currentTarget.data as String);
	var request:URLRequest = oauth.getAuthorizeRequest("http://twitter.com/oauth/authorize", requestToken.key);
	// opens website where user has to login on Twitter and gets 6 digit pin code
	navigateToURL(request, "_blank");
}
 
function getAccessToken(pin:int):void
{
	var loader:URLLoader = oauth.getAccessToken("http://twitter.com/oauth/access_token", requestToken, {oauth_verifier:pin});
	loader.addEventListener(Event.COMPLETE, accessTokenHandler);
}
 
function accessTokenHandler(e:Event):void
{
	accessToken = OAuthUtil.getTokenFromResponse(e.currentTarget.data as String);
	// TODO store accessToken.key and accessToken.secret in EncryptedLocalStorage for all further requests
}

Instead of opening the Twitter authorization page in the browser the library also contains OAuthLoader which is a wrapper around HTMLLoader which enables to directly show the authorization page within an AIR window:

// use this in the requestTokenHandler instead of navigateToURL
var loader:OAuthLoader = new OAuthLoader();
loader.load(request);
loader.percentWidth = 100;
loader.percentHeight = 100;
var w:Window = new Window();
w.width = 800;
w.height = 400;
w.title = req.url;
w.addChild(loader);
w.open();

The OAuth library is not only considered to be used with Twitter but this was the first thing I have tested from AIR. When you build a web client there will be no pin mechanism but I haven’t tested this yet. If you have it working or see problems/bugs for web clients please drop a comment a or better file a bug.

Big thanks to Shannon Hicks for his core oauth as3 library and to Masayoshi Sekimura for the example which got me started.

Links

Width Problem with Firefox

Recently I ran into a problem that I had to build a Flash movie which should fit the browser window meaning the Flash movie is embedded with 100%x100%.
The problem I had is that even if I resized the browser window to something like 400×400 the stage.width property still showed 662. This caused that the content layout was wrong because it should take a width of 400 but used 662.

I investigated a bit more and it came out that this is caused by my Firefox browser where I tested the content. When I tested with Safari the minimal width my stage could get was 392 pixel. So WTF is happening here?

Then I tried to disable all Firefox toolbars and voilá, it worked like expected. Without any toolbar my flash content resized correctly to the actual size of the browser window.

Conclusion: Firefox with toolbars enabled prevents that the Flashplayer stage gets below a specific width depending on the stuff you have in your toolbar.
If you want to test small width Flash content which is embedded with 100%x100% be sure to disable all Firefox toolbars.

You can easily test it with this code for Flex:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
	resize="resizeHandler(event)">
 
	<mx:Script>
		<![CDATA[
 
			private function resizeHandler(e:Event):void
			{
				if(stage != null)
				{
					trace("stage width " + stage.width);
				}
			}
 
		]]>
	</mx:Script>
 
</mx:Application>