Packaged Web Apps with PhoneGap

Adobe acquired PhoneGap a little over a year ago because it was and continues to be the leading solution for Mobile Application developers who want to use their HTML5 skills to create native applications.

Essentially, PhoneGap lets a developer write HTML, JavaScript and CSS content, use mobile APIs providing much needed functionality (such as device orientation, access to the address book or location) which is not always yet available in browsers and package these applications as native ones so they can be distributed in application stores such as Google Play or the Apple AppStore.

PhoneGap is the solution that is based on the open source Apache Cordova project, similar to the way the Chrome browser, for example, is based on the WebKit open source project.

Since PhoneGap is using an open source platform targeted at developers and created by a community, the following gives recent updates about the different aspects.

Platforms

Despite the holidays, there was a flurry of activity in the mobile web world. The Cordova team released 2.3 with full support for Windows 8 and Windows Phone 8 (Window 8 support was added in 2.2). The popular iOS and Android projects saw more performance and bug fixes. Long anticipated BlackBerry 10 is shipping this month with complete support. Working closely with Mozilla, the team also has Firefox OS on the horizon early this year. 

Tools

New common Command Line Interface (CLI) tooling is progressing to beta quality for building projects. The plugin tooling is now quite mature for iOS and Android. Work is now starting to migrate the core API to plugins, and add support for BlackBerry and Windows Phone. The Ripple emulator received much love in December bringing in beta quality support for remote device proxy and the ability to host Ripple. Also good news, the long awaited PhoneGap/Build CLI is ready for beta, integration to the PhoneGap release can be expected in the coming releases.

Community

An open source community health is directly proportional to the activity on the code. Operationally speaking, Cordova offers monthly stable source-only releases and a bleeding edge development channel. However, things are progressing and we will likely see stable, beta, and dev channels available in Cordova 2.4. The project has matured in adoption enough to justify this third release channel for developers that want to be on the bleeding edge. The team will continue to ship PhoneGap on the same cadence. 

We added one committer from IBM in December, and have seen two new contributors become active in the project from the Google Chrome team.

Flash Support on Windows 8 and Metro

We expect Windows desktop to be extremely popular for years to come (including Windows 8 desktop) and that it will support Flash just fine, including rich web based games and premium videos that require Flash. In addition, we expect Flash based apps will come to Metro via Adobe AIR, much the way they are on Android, iOS and BlackBerry Tablet OS today, including the recent number one paid app for the iPad on the Apple App Store, Machinarium, which is built using Flash tools and deployed on the Web using Flash Player and through app stores as a standalone app.

Adobe is about enabling content publishers and developers to deliver the richest experiences for their users, independent of technology, including HTML5 and Flash. We are working closely with Microsoft, Google, Apple and others in the HTML community to drive innovation in HTML5, to make it as rich as possible for delivering world-class content on the open Web and through App Stores.

We are excited about the innovation and opportunities that are available to our customers and Adobe as the web and platforms evolve across devices, including Windows 8 and Metro.

UPDATED: 9/15/11

The Problem with Technology Silos and Where Flash/HTML can Lead

There is a cool workshop being given by Jamie Kosoy called No Flash? No Problem and he had a great quote in the description:

There’s a long list of common complaints about the use of Flash, but many of the criticisms just aren’t true. Detractors say that Flash isn’t search engine friendly; Screen readers can’t understand Flash content; You can’t deeplink to specific pages…

You know what? They’re wrong. These criticisms are symptoms of misunderstanding by developers on the ways different technologies work together.

I think this is one of the biggest problems that Adobe has. Technology and development choices tends to be borderline religious in nature. And technology in general loves to have good guys and bad guys. That means the communities are very siloed and there is some resistance to incorporating or looking at other technologies. It’s HTML5 versus Flash, Microsoft versus Google, .NET versus Java, etc.

It’s also become a lot harder to be a generalist. Developers get rewarded (at least in terms of attention) for becoming experts in their niche. They’re asked to speak at conferences, they get better gigs, so becoming an expert has direct financial and publicity benefits. Who has time to dive into other technologies when there are so many advantages to drilling down into your own?

Because of that, I don’t think we’re seeing technology at its best. And it’s not limited to Flash. PhoneGap has been very successful by combining the iPhone with HTML/JS. But Flash suffers more than most. There are a lot of great integration points between HTML and Flash. We’ve got the Flex/Ajax bridge for Flex that lets you expose Flash methods to JavaScript and vice versa. We’ve got deep-linking support with SWFAddress that uses JavaScript and Flash. There are a lot of integration points but they don’t seem well publicized or well used. And there are no shortage of areas where Flash can augment JS/HTML to solve problems. File uploading, Webcam/Mic support, and charting.

But I also think Adobe is at fault. I don’t think we’ve done a good enough job of making it easy to integrate Flash and HTML. Even now internally you hear things like “HTML strategy”, or “HTML versus Flash” and I haven’t heard a lot of talk about how we’re going to take what we know about RIAs and web apps and apply that to both Flash and HTML.

But I think that’s changing. So part of the post is to give heart. We recently had a big re-organization and most of the Creative Suite web tools and the Platform (Flash/AIR/Flex,etc) are together in one business unit. I think that means you’re going to see a lot of Flash-knowledge applied to our HTML tools and hopefully you’ll see a lot more about using Flash and JavaScript together so we don’t need sessions like Jamie’s a year from now.

With the web design tools and developer tools in one place, I’m looking forward to talking a lot more about rich web solutions that provide some innovative examples of technology working together and encouraging HTML/JS developers to look at Flash where appropriate and Flash developers to think about HTML/JS when it makes sense. The easier we can make that for developers the more success we’ll have and the better applications we’ll see.

Flash Player Will Support VP8

As Kevin Lynch mentioned today at Google I/O, we are excited to include the
VP8 video codec in Flash Player in an upcoming release, which will help
provide users with seamless access to high quality video content on all of
their Internet-connected devices. Today, VP8 was released as
open source by Google as part of the WebM effort.

Companies distributing video online need the freedom of choice to deliver
the right experience for their customers and their business. We have a
legacy of embracing standards, such as H.264 and HTTP, in our video delivery
stack and are excited to be building on this with the inclusion of VP8.
Today, approximately 75% of video online is viewed using Flash Player
because it provides the reach and consistency that companies need as well as
additional capabilities, such as content protection, measurement and
monetization opportunities that are critical to driving their business on
the web. By adding support for VP8 to Flash Player we will extend the
ability to use these critical capabilities with this media format and
provide content owners the freedom of choice in how they deliver video.

We will drive Flash Platform innovation well into the future, partnering
with our customers to develop end-to-end solutions that enable them to
create, deliver, and optimize their content across any device or screen
using one, unified workflow. By including VP8 as part of the Flash Platform,
we’re providing companies with a choice as to how they can work with and
deliver great experiences to the web. We are excited to work with Google and
others to ensure web video continues to evolve and better serve content
publishers, web developers and end users.

Visit the Google WebM page to learn more about the project.

GIO.jpg

Flash Builder for Dreamweaver CS5 Users

Thanks to everyone who stuck out the preso on Flash Builder for Dreamweaver CS5 users. Clearly this isn’t my month for demos. I’ve uploaded the slides as well as the (working) source code. There are two directories, the Flex directory which includes the source code for the Flex projects and the html directory which includes the HTML code.

It’s got examples for using ExternalInterface, the Flex/AJAX Bridge, and FlashVars. You can grab it here.

Flash and Standards Cold War

Very good perspective on Flash and standards.

Both the standards community and the Flash community are extremely good at sharing knowledge and supporting the people within their respective groups. The relationship across communities, however, isn’t nearly as cordial. Two things are happening: either the people within each camp stay to themselves, or one ignorantly hurls insults at the other.

I love that angle. Both camps have very passionate communities but the problem is that there’s not enough cross-pollination between groups. Part of that is that (I don’t think) Flash has done a good job of playing well with HTML. It has been and still is largely a black box. So at a technical level the two technologies don’t work as well as they should have. That carries over into the communities. As a company that makes tools for both HTML and Flash, it behooves us to be involved in both sides of the debate. My hope is that as Flash opens up more and hopefully works better with HTML, the people on both sides will start to work more closely as well.

HTML-Flash Geo

HTML and Flash working together to find each other.

Geolocation is a good example. HTML5 is going to get a geolocation API that works just beautifully even on devices with no GPS. Flash based applications will (currently) only get access to geolocation APIs when targeting the AIR runtime on mobile. Some browsers (I only know of Firefox 3.5 on Mac and the WebKit browser on the Nexus One) already support the HTML5 geolocation API… So why not use that to get geo information into your Flash based application?

There are few things I love more than geography and by extension, geolocation. It’s the digital overlay of the world. How can that not be cool? And this particular example is nice because it’s an area where HTML5 is ahead of Flash Player. Just like HTML can use Flash to implement ideas it hasn’t nailed down yet, Flash can use HTML to implement ideas that it hasn’t got yet. Bliss.

Non-Accessible HTML

YouTube opens up captioning for all videos….sort of.

I know I work for Adobe, but this is the kind of thing that pisses me off. Flash gets such a bad rap from the open standards crowd who hold accessibility so highly but as of right now there isn’t any way to do captioning in HTML5 videos. So when YouTube makes a big announcement about improving and enhancing accessibility by adding captions to all of their videos, no one mentions that it’s just the Flash videos.

I realize that the HTML5 feature on YouTube is in beta, but it isn’t like this is something that anyone has figured out yet for HTML5 video. It’s listed as “unwritten documentation” on the Chromium site which basically means “we aren’t sure how this is going to work”. But no one does. The closest thing I’ve found is a jQuery plugin that’s in the early stages.

Not only is there no clear codec for HTML5 (something that in theory Google will remedy with the purchase of On2) but captioning support, something that Flash has made easy and ubiquitous, isn’t a feature that’s looking like it will be implemented soon.

But it’s going to kill Flash….riiiiiiiight….

Flex and PHP: Authentication With an HTML Login Page

One of the first things to think about when building a Flex application is how you’re going to do authentication. Most people seem to include a username and password box in Flex and then make an HTTPService or AMF call to pass the authentication credentials. But I hate that solution. Most major browsers now have support to save usernames and passwords with autocomplete and that’s become something people expect from their logins. I think it’s also important to be able to clear the “remember me” cookie just like any other cookie as opposed to having it saved in a Flash cookie. Whenever you can provide the behavior people expect from their browser, you should.

So in this example I’m going to show how you might implement an HTML form with PHP for a Flex application. As I’m new to PHP there may be some bad practices here but I’ll update the post as I get feedback.

Creating the login page in PHP and HTML

To start, we can just use PHP’s built in session functions to create the session variables and build the login page called login.php. You start off by creating a session with session_start() and then you set some session variables to their defaults. Then you’ll show the username and password fields only if the form hasn’t been submitted and use the $_SESSION variables to store the information from the user. Finally, when everything is authenticated you use the header() function to send the user to the Flex application.

<?php
session_start();
$_SESSION['logged_in'] = false;
$_SESSION['username'] = "";
 
if(isset($_POST['is_submitted']))
{
$username = $_POST['username'];
$password = $_POST['password'];
 
// If the "Remember my username" box is checked
// then we use the setcookie function to save it.
// Otherwise, we clear it out. 
if($_POST['keep_username'] == true)
{
setcookie("username",$username,time()+36000);
} else {
setcookie("username");
}
 
// This is where you would look up the username
// and password. Normally this would be an LDAP call
// or a query to a database. In this case, I'm just
// accepting everything.
if($username && $password)
{
// Set our session variables.
$_SESSION['logged_in'] = true;
$_SESSION['username'] = $username;
 
// Redirect to the Flex application
header("location:flex/index.php");
} else
{
echo "Go back and put in a username and password.";
}
} else {
?>
 
<form name="login" action="<?php$_SERVER['PHP_SELF'] ?>" method="post">
Username: <input type="text" name="username" value="<?php echo $_COOKIE['username']; ?>" /><br/>
Password: <input type="password" name="password" /><br/>
Remember my username: <input type="checkbox" name="keep_username" value="true"><br/>
<input type="hidden" name="is_submitted" value="true" />
<input type="submit" value="Submit" />
</form>
 
<?php
}
?>

Notice the keep_username checkbox above. If the user checks that, you use the setcookie() method to create a cookie that will store the username on the next visit. If it is unchecked, the username will be blank.

Setting up the Flex Project

Even though most Flex applications take up the entire page, nearly all of the time you embed the actual SWF file on an HTML page. In Flash Builder when you create a new Flex application in creates the SWF files and the HTML files for you that embed your application. To do that it uses a template file that you can find in the html-template folder of your project. If you haven’t done so yet, go ahead and create a new Flex project. Use the defaults (do not use PHP as the server, leave it at None/Other). When you get to the second screen, set the output folder to a subdirectory named “flex” in the directory where your login.php file is located.

With the project created the first thing you’ll want to do is edit the template file. Go into the html-template directory and rename index.template.html to index.template.php. That will let you run PHP code inside of the template file. Flash Builder will automatically create an index.php file in the flex folder you specified in the create project wizard. Next you need to make sure your application will use the right file when you run or debug it. Right click on your project, select properties, and then select Run/Debug Settings. Now select your project in that box and click the “Edit” button. On the next screen, uncheck “Use default” in lowest box and put in the path to your application. You can see mine below (I’ve got http://localhost:8888 mapped to http://rainier.cascade.mtn but your local PHP server will probably use http://localhost).

Modifying the Index Template

Next you need to edit the template we just renamed. Open it up in Flash Builder (or your favorite text editor) and you should see a bunch of HTML. At the very top of that page you’re going to add some PHP code. First, you are going to check for a url parameter of logout to be passed. If it is, you destroy the session and log the user out. If that isn’t passed, you’re going to use the session information from your login page and save that information to variables on this page. This code goes at the very top before all of the HTML in your template page.

<?php
// Always start the session first.
session_start();
 
// You will also use this page to log out. If 
// ?logout=1 is passed in the URL, destroy the 
// session and log the user out.
if(isset($_GET['logout']))
{
if($_GET['logout'] == 1)
{
$params = session_get_cookie_params();
setcookie(session_name(),"", time()-3600,
$params["path"], $params["domain"],
$params["secure"], $params["httponly"]);
session_unset();
session_destroy();
}
}
 
// Create the default values for our session.    
$session_id = "";
$logged_in = false;
$username = "";
 
// If the session is valid, replace the default
// values with our session values.
if($_SESSION['logged_in'] == true)
{
$logged_in = true;
$session_id = $_COOKIE['PHPSESSID'];
$username = $_SESSION['username'];
?>

Now that your variables are set, you’ll send those to the Flash Player. There are a number of ways to get data into your Flex application but the most straight forward is to use a concept referred to as “flashvars”. Flashvars are parameters you can put within the embed code that will then be accessible by the Flex application. Flashvars are a great way to take a dynamic site, like one written in PHP, and change the behavior of a Flex or Flash application based on that dynamic PHP data. Look for the JavaScript in the template that includes var flashvars = {} and replace it with this code.

var flashvars = {session_id:"<?php echo $session_id; ?>",
logged_in:"<?php echo $logged_in; ?>",
username:"<?php echo $username; ?>"};

That code will make those three variables available to your Flex application. That way before you let the user do anything in your Flex application you can check to make sure the user is logged in correctly.

Finally, at the end of the template you’ll add some code to show the user an error message if they try to access the page without logging in.

<?php
} else {
echo "Not authorized, go back and log in.";
}
?>

Creating the Flex Application

In this example you’ll just create a very, very basic Flex application with two states, a beginning state and a logged in state. When the application loads, check the flashvars you added to the embed code and then change to the logged in state. In the logged in state also contains a button that uses the logout functionality you added to the template code. Here’s the whole Flex application.

<?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"
minWidth="955" minHeight="600" currentState="startingScreen"
creationComplete="application1_creationCompleteHandler(event)">
 
<fx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.events.FlexEvent;
import mx.utils.ObjectUtil;
 
protected function btn_clickHandler(event:MouseEvent):void
{
navigateToURL( new URLRequest( encodeURI("index.php?logout=1")), "_self");
}
 
protected function application1_creationCompleteHandler(event:FlexEvent):void
{
if(this.parameters.logged_in == 1)
{
currentState = 'loggedIn';
}
}
 
]]>
</fx:Script>
 
<fx:Declarations>
<s:State name="startingScreen" />
<s:State name="loggedIn" />
</fx:Declarations>
 
<s:Panel name="Test" left="25" right="25" top="20"
bottom="25" title="My Application">
<s:Button id="btn" left="10" top="10"
click="btn_clickHandler(event)"
label="Log Out" includeIn="loggedIn" />
<s:Label id="lbl" left="10" top="10"
text="You need to log in"
includeIn="startingScreen" />
</s:Panel>
 
</s:Application>

Conclusion and Warnings

There are a couple of notes and warnings about this method. By using two states and checking the login parameters you aren’t just depending on the embed code. That means if someone browses right to the SWF file they won’t be able to access the application because it won’t move to the next state unless it gets those parameters. That’s also part of the problem in this very simple application.

In the Flex code that changes the state I just check to see if the flashvar logged_in is set to 1. If you were to download a local version of the PHP file as well as the SWF and change that embed code you’d have access to the application. In a more robust example you would want to add a couple of hooks into the database. One way to do that would be to store the session id and the username in the database in the login.php file. Then when your Flex application loaded you could make a call to another PHP page and pass the session id and username parameters to a function which would compare it to the session and username that were stored during login to make sure it matches up.

You might also want to implement a token system with a shared secret which is a good way to authenticate against external APIs, the kind that you would create in PHP and consume in a Flex application using AMF or REST.

So keep in mind that this isn’t ready for production. But hopefully it gets you started in the right direction when creating a PHP/Flex application that is going to use an HTML login form. The fewer Flex/Flash login forms there are the better.