Cookbook Draft is Half-Way Cooked

Cookbook Draft
Yeah- I hit a pretty big milestone this week with the draft for my book on Android and Flash Platform development (the book is still untitled). I’ve submitted 5 chapters and am mid-way through a 6th. This actually places me about a month and a half ahead of schedule, which is pretty darn good. 180 pages!!!

Some Thoughts

The process so far has been a lot like writing a bunch of small articles. I’ve handled it in a similar way to writing an album – one track/chapter at a time. Things are definitely overwhelming if you think about the entire work as a whole. If I didn’t segment my work like this, I’d probably stress about it so much that I’d get nothing done. It is often the half way point on a large project like this when you realize just how much things are actually coming together. Quite gratifying.

There are negatives to this entire process as well; I haven’t had a lot of free time for other projects, have had to pass up on some additional development opportunities through Fractured Vision Media, and it’s incredibly hard to balance family life along with everything I do. I’m fairly certain the positives will win out when this is all over though!

Dropbox and Word

I’ve been using the excellent Dropbox service for revisions, automated backups, and simply sharing drafts across my studio machine and laptops. It has made document management absolutely painless and I highly recommend it to anyone involved in such a project. It has provided me with convenience and peace of mind!

On the dark side of things… I’ve been using Microsoft Word for all of my word processing and formatting. Enough said.

Revisions

After submitting the first couple of chapters, I had quite a few revisions to do dealing with formatting and even the structure of a lot of my recipes. It has turned out well though; as the recipes in their current form are quite simple to follow along with. I’ve actually used some of them for reference in my own development work!

While I’ve come quite far; I’m sure there will be many more revisions to come. These are just drafts and I have additional feedback from technical reviewers to work through. Really pleased with the foundation thus far.

Outlook

Like I mentioned above; things are looking good! My editor is pleased with the quality and timeliness of the draft chapters and we are in the process of defining a title, generating promotional copy, gathering technical reviewers, and should be announcing everything on the Packt Publishing site in the next week or two!

I’ll post another update once this has occurred so you can all pre-order ;)

ActionScript 3 Google Analytics API

Over on the Google Analytics weblog, they’ve posted about a new (official) AS3 library for GA! Apparently, the library is pretty robust, featuring; Metrics, Dimensions, Filters, Sequenced Pagination, and Data Views.

ActionScript 3 library for Google Analytics

I’ve dealt with Google Analytics and Flash in the past using the Google Analytics Tracking For Adobe Flash ActionScript 3 API which, from my experience, is still very useful. I even did a session on it at the FITC Unconference during Adobe MAX 2009.

Grab the code or check out a quickstart.

CodeBass Article: AS3 Audio Libraries

Audio Tests

An article I had written on using a variety of ActionScript and Alchemy-based audio encoding libraries in Flash Player has been published over at CodeBass.

Check it out and even play with the demo set from within your web browser. Full source code and links to referenced AS3 libraries is also available.

Nice to finally get something up there!

Parsing Tweets with the TwitterString Class

While building a little Twitter aggregator for an upcoming conference, I found myself in need of a set of methods to create hyperlinks from three distinct elements that can be included within a tweet; links, usernames, and hashtags.

I was able to find regular expressions to do all the heavy lifting from various sources on the Web and have created a class which pretty much does all the processing with one method call. Here’s an example of the thing working, followed by example code, and the class itself.

Example SWF

Flash Player 11.2 or greater is required!


Example MXML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
			   xmlns:s="library://ns.adobe.com/flex/spark" 
			   xmlns:mx="library://ns.adobe.com/flex/mx" 
			   creationComplete="init()" width="300" height="100" 
			   backgroundColor="#1E1E1E" preloaderBaseColor="#989898">
 
	<fx:Script>
		<![CDATA[
			import flashx.textLayout.elements.Configuration;
			import flashx.textLayout.elements.TextFlow;
			import flashx.textLayout.conversion.TextConverter;
			import flashx.textLayout.formats.TextLayoutFormat;
			import com.fracturedvisionmedia.utils.TwitterString;
 
			private var myTxt:String = "Everyone should follow @josephlabrecque (http://bit.ly/7NkqrB) - really cool stuff and super-informative insights! #Awesome #Super #LOL";
 
			private function init():void {
				// Configure styling the TextFlow links to match richTxt
				var cfg:Configuration = TextFlow.defaultConfiguration;
				var normalTLF:TextLayoutFormat = new TextLayoutFormat(cfg.defaultLinkNormalFormat);
				normalTLF.color = 0xDCD9D9;
				cfg.defaultLinkNormalFormat = normalTLF;
				TextFlow.defaultConfiguration = cfg;
 
				// Import tweet as HTML
				richTxt.textFlow = TextConverter.importToFlow(TwitterString.instance.parseTweet(myTxt), TextConverter.TEXT_FIELD_HTML_FORMAT);
			}
		]]>
	</fx:Script>
 
	<s:RichEditableText id="richTxt" selectable="false" editable="false" right="10" top="10" bottom="10" color="#DCD9D9" left="10"/>
 
</s:Application>

TwitterString Class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package com.fracturedvisionmedia.utils {
 
	/**
	 * The TwitterString class assists with the parsing of a tweet to add hyperlinks 
	 * around Links, HashTags, and UserNames in a tweet.
	 * @author Joseph Labrecque
	 * v. 0.1.2
	 */ 
 
	public final class TwitterString {
		private static var _instance:TwitterString = new TwitterString();
 
		public function TwitterString(){
			if (_instance != null){
				throw new Error("TwitterString can only be accessed through TwitterString.instance");
			}
		}
 
		public static function get instance():TwitterString {
			return _instance;
		}
 
		public function parseTweet(t:String):String {
			var step1:String = parseHyperlinks(t);
			var step2:String = parseUsernames(step1)
			var step3:String = parseHashtags(step2)
			return step3;
		}
 
		private function parseUsernames(t:String):String {
			var result:String = t.replace(/(^|\s)#(\w+)/g, "$1#<a href='http://search.twitter.com/search?q=$2' target='_blank'>$2</a>");
			return result;
		}
 
		private function parseHashtags(t:String):String {
			var result:String = t.replace(/(^|\s)@(\w+)/g, "$1@<a href='http://www.twitter.com/$2' target='_blank'>$2</a>");
			return result;
		}
 
		private function parseHyperlinks(t:String):String {
			var urlPattern:RegExp = new RegExp("(((f|ht){1}tp://)[-a-zA-Z0-9@:%_\+.~#?&//=]+)", "g")
			var result:String = t.replace(urlPattern, "<a href='$1' target='_blank'>$1</a>");
			return result;
		}
 
	}
}

Download TwitterString

Quick Tip: Display Application Version in your AIR App.

Just a quick tip for those looking to somehow display the AIR application version from the descriptor file. I’ve found it very helpful in troubleshooting is users can say EXACTLY what version of the app they are running.

Application Version

AIR 2.5 and later:

private function getAppVersion():String {
	var appXml:XML = NativeApplication.nativeApplication.applicationDescriptor;
	var ns:Namespace = appXml.namespace();
	var appVersion:String = appXml.ns::versionNumber[0];
	return appVersion;
}

Older versions of AIR:

private function getAppVersion():String {
	var appXml:XML = NativeApplication.nativeApplication.applicationDescriptor;
	var ns:Namespace = appXml.namespace();
	var appVersion:String = appXml.ns::version[0];
	return appVersion;
}