Category Archives: Adobe AIR

Not adding fuel to the Flash fire

Image of tree branches

I’m not going to add any flames or speculation for what the recent choices Adobe has made in regards to mobile Flash, Flex, AIR, or JavaScript/HTML5. There is already plenty of that out there and it’s hard to know what is FUD, what the Adobe FAQ answers truly mean moving forward, or if some people just like taking shots at Flash because they think it sucks. Go read that at your leisure and make of it what you will.

If you’re at all concerned with Flash falling by the wayside, you have a few options that I can think of

 

  • Hope that nothing changes for you and you can keep putting Flash-assisted cash in your bank account. Assume that nothing is changing or that it won’t affect you.
  • Start to learn some JavaScript techniques and general HTML5 approaches to make up for any Flash application drop off. Start branching your toolbox just a little bit in case a client starts harping about HTML5 because it’s in the news more lately.
  • Start jamming on AIR for Android and iOS so you can offer something up to those platforms in a round-about way without committing to hunkering down and learning totally new stuff.
  • Start jamming on Android Java and iOS Objective-C so you can offer up some native goodness to those platforms. Leave the optimization headaches and late-adopter OS-version capabilities to other developers.

I am always in favor of rounding out your capabilities as broadly as you can. Push yourself a bit more. Flash has been a mainstay technology for a great many of us for quite a long time. Some of us got our start and remain profitable (employable) being one-trick Flash ponies. Some of us have branched out and used Flash as a springboard to other languages and platforms.

Things change in this technology field, and you have to be open to that change if you want to stay on top of the game. And remain in high demand. It’s my personal belief that if you haven’t started to branch out yet because you’ve got AS3 nailed and you love it, I’d suggest you start branching now. It will only help you as a developer anyway… when you pick up bits of other languages you’ll improve all around in how you approach coding projects in any language. You’ll start to think more broadly about what you’re doing.

I’ve been tooling with Android and iOS (both natively) for some time now and I can almost pump out apps in the same amount of time that they took in AS3/Flex. So now I can offer native Android, native iOS, Mac OS X, Flex, AS3, and AIR as options. I haven’t done the AIR for mobile yet because I don’t like having some magic sauce do magic things underneath me. I do value the superior portability of platform it can bring though.

Once you branch you’ll see how similar many languages are to one another. Same ideas just different syntax and approaches – so having AS3 under your belt will get you a jump start on other languages.

Branch out… it’s a ton of fun!

Remember the promise of Saffron UML? Look to Crocus Modeler

A few years ago something pretty awesome looking was much talked about. It was an AS3 UML modeler given the name of Saffron. Many a developer drooled over this tool vaporware. I was among them.

People rumored that it was purchased by Microsoft before being released. Rumored to still be in development, etc. To be honest, I don’t know what happened to the project, but as far as I am aware, it never saw the light of day.

If you work on smaller AS3 projects, you probably didn’t care very much, but for those of use working on larger applications, it would have been a very useful tool. Well, there is now something called Crocus Modeler (I fixed the spelling). It looks to provide similar technology, it’s just not as slick in it’s UI. But guess what… this is a UI that you can actually use.

Give the tool a spin & comment on what you think of it. I have played a little bit with it and it’s pretty cool so far!!

Interaction design and mobile computing

mobile image

 

There is coming a time when potentially most of those who interact with connected devices will have never owned a traditional personal computer (ie. desktop or even laptop). Trends are already leading this direction.

The future may allow for Flash and HTML 5 or other interactive technologies to exist in order to guide those users through their day-to-day tasks using mobile computing devices. People may soon forget what a cable modem or even what a router is. It’s our job as designers and developers to provide and guide their interactions with application data in interesting and unique ways.

Desktop operating systems are adding more and more “connected” technologies into them because the writing is on the wall. Devices are now out-selling PCs and if they can train users into certain ways of interacting with machines that you find usable and satisfying, you may decide on a new device with their mobile OS for your use.

What will be the fate of the mouse? Will it die? Will keyboards be replaced via listening devices that convert your vocal commands as input? Will devices watch you with their camera(s) (think Kinect+)? What sort of gestures will win and which will lose favor? Will the desktop die a slow and painful death, or will it hang around for certain applications?

There is a lot of really interesting technological things going on, even in this rotten economy. There is this notion of a Flash versus HTML 5 battle being waged… and for now there does seem to be a battle, but only by large companies fighting for mindshare. In the end, whatever works best for users will matter. It is for this reason I feel that Flash and different but related technologies will co-exist until eventually one of them dies out in favor of the other. Who is to say something brand new won’t replace both options?

It’s amazing to think about legions of people going through their daily lives who will never own a traditional PC or use home WIFI in their lives. It is happening now. As time marches on, it will continue to happen to larger counts of people. Users. Clients. Try to keep all of this in mind when you are deciding on what next to pursue in your profession. Just keep an eye on the user experience and how less mouse-driven it’s all becoming. It’s about touch, gestures, surfaces, movements, frameworks, memory, media, and of course hardware.

These are exciting times we find ourselves living in. I am happy to be around while all of this takes place and while I am able to interact with and perhaps even drive a little tiny bit of it one way or the other. I won’t call this a rant… I choose to call it my 10 minutes of positive and dreaming blog authoring.

A Sports Companion App Idea

I’m a sports homer – much preferring to listen to my sports team’s local radio broadcast instead of some lame national broadcasters waxing poetic about some nonsense. So I like to watch the broadcast in HD and try to listen to a home town radio broadcast over the internet. Think WDVE. However getting the two in sync is impossible.

If the broadcast adds a delay (in case someone says something offensive) or the internet stream is a bit behind, etc. you end up listening to the play-by-play to visuals that don’t match. It’s annoying enough to just say hooey to the whole thing and resort to dealing with the national broadcasters.

It would be cool to add something to internet audio broadcasts that would allow one to dial in an amount of delay to try and match the TV broadcast. Of course if the internet stream is behind the TV there is nothing one could do. The out of sync issue may not be a huge deal for some, but for me if it’s even off a little I find it annoying.

Anyway, it’s something that I haven’t seen out in the wild yet that a few people might find useful if created.

flash.net.ServerSocket is sticky sweet

I have just discovered the ServerSocket class and I have made an AIR2 (required) server socket application with it. I’ve tested it locally so far (127.0.0.1, 0.0.0.0 ) and it seems to be working fine with a regular application I made using Socket to talk with it. I tried getting another copy of the socket app to talk to the socket server from another machine on the network, but I think a LAN might work better for testing at the moment since I don’t know the dynamics of the huge network that exists at work.

I will be adding some code to this post once I’m sure it’s mostly worked out. The socket server is made outside of Flex, but that shouldn’t change much if you are using Flex to author your AIR 2 application.

Here is an event class I am using with my socket class:

package {
   import flash.events.Event;
   public class SocketEvent extends Event {
      public static const DATA_RECEIVED:String  = "received";
      public static const CONNECTED:String      = "connected";
      public var params:Object;
      public function SocketEvent( $type:String, $params:Object,
                            $bubbles:Boolean = false,
                            $cancelable:Boolean = false ){
         super( $type, $bubbles, $cancelable );
         this.params = $params;
      }

      public override function clone():Event {
         return new SocketEvent( type, this.params, bubbles, cancelable );
      }
      public override function toString():String {
         return formatToString("SocketEvent", "params", "type",
                          "bubbles", "cancelable" );
      }
   }
}

And here is a socket server class (in an unfit state, but I present it prior to clean-up and testing):

package {

   import flash.display.Sprite;
   import flash.errors.IOError;
   import flash.events.Event;
   import flash.events.MouseEvent;
   import flash.events.ProgressEvent;
   import flash.events.ServerSocketConnectEvent;
   import flash.net.ServerSocket;
   import flash.net.Socket;
   import flash.text.TextField;
   import flash.text.TextFieldType;
   import flash.utils.ByteArray;

   public class SocketServer extends Sprite {

      private var serverSocket:ServerSocket = new ServerSocket();
      private var clientSocket:Socket;

      public function SocketServer(){
         setupUI();
      }

      private function onConnect( event:ServerSocketConnectEvent ):void {
         clientSocket = event.socket;
         clientSocket.addEventListener( ProgressEvent.SOCKET_DATA, onClientSocketData );
         log( "Connection from " + clientSocket.remoteAddress + ":" + clientSocket.remotePort );
      }

      private function onClientSocketData( event:ProgressEvent ):void
      {
         var buffer:ByteArray = new ByteArray();
         clientSocket.readBytes( buffer, 0, clientSocket.bytesAvailable );
         var recString:String = buffer.toString();
         recString = recString.replace(/\n/g,'');
         recString = recString.replace(/\r/g,'');
         //log( "Received: " + buffer.toString() );
         log( "Received: " + recString );
      }

      private function bind( event:Event ):void {
         if( serverSocket.bound ) {
            serverSocket.close();
            serverSocket = new ServerSocket();
         }

         try {
            serverSocket.bind( parseInt( localPort.text ), localIP.text );
         } catch( error:Error ){
            log( "Error: bind() attempted on invalid socket." );
         }
         serverSocket.addEventListener( ServerSocketConnectEvent.CONNECT, onConnect );
         serverSocket.listen();
         bound_txt.text = "Bound to " + serverSocket.localAddress + ":" + serverSocket.localPort;
      }

      private function send( event:Event ):void {
         try{
            if( clientSocket != null && clientSocket.connected ){
               clientSocket.writeUTFBytes( message.text );
               clientSocket.flush();
               log( "Sent message to " + clientSocket.remoteAddress + ":" + clientSocket.remotePort );
            }
            else log("No socket connection.");
         } catch ( error:Error ){
            log( error.message );
         }
      }

      private function log( text:String ):void {
         logField.appendText( text + "\n" );
         logField.scrollV = logField.maxScrollV;
         trace( text );
      }

      private function setupUI():void {
         bind_btn.addEventListener( MouseEvent.CLICK, bind );
         send_btn.addEventListener( MouseEvent.CLICK, send );
         clear_btn.addEventListener( MouseEvent.CLICK, clear );
         this.stage.nativeWindow.activate();
      }

      private function clear( event:MouseEvent ):void {
         logField.text = "";
      }
   }
}

Adobe AIR and included files

Have you as a developer ever wanted to deploy an Adobe Air application and include files with the installation? Say an XML file for settings and the like? Well, you can include files well enough (to the applicationDirectory), but if you want to write back to that file you’ll get an error. You see, files in the applicationDirectory are read-only.

So what do you do? You’ll need to read that file in the applicationDirectory and then copy it over to the applicationStorageDirectory… or desktopDirectory or even the documentsDirectory. Then you’ll be able to read and write to the file.

The snippet below sets up a reference to a test text document I included in an AIR application. It exists in the protected applicationDirectory. Then the destination (of applicationStorageDirectory) is referenced. If the file doesn’t already exist in the destination location, the one in the applicationDirectory is copied over to the applicationStorageDirectory… and traces “Copy Done” for me.

If you ever wanted to reset the settings file, all you would need to do is to copy over that original included Test.txt file to your applicationStorageDirectory again, over-writing the one that was already there. I didn’t see anything like this in my Google searches, but I did hear of the technique. Here is a little code that shows it in action.

var testFile:File = File.applicationDirectory.resolvePath("Test.txt");

//Copy the file over.

var destination:File = File.applicationStorageDirectory;
destination = destination.resolvePath("Test.txt");

//Only copy the file from the installation bundle if it 
//doesn't exist in the applicationStorageDirectory

if( !destination.exists ){
   if( testFile.copyTo(destination,true)){
      trace("Copy done");
   }
}

One thing to note – on a Mac, the applicationStorageDirectory exists here: username/Library/Preferences//Local Store/

Of course it exists elsewhere on a PC and Linux, but the applicationStorageDirectory reference takes care of that for you on the different operating systems. You should check your Local Store just to make sure it’s doing what you need it to do.