Bookboard – A Model for the Future of the Web

One of the missions of PhoneGap has always been to bring about its own demise. The PhoneGap team wants the web to have all the functionality that we currently enjoy on devices so that there isn’t a need for PhoneGap to exist. It’s one of the reasons I love the project; I think that’s the perfect goal. I hope we get away from app stores and back to a world where the web rules all. There are obviously many things that have to happen before that becomes a reality but every once in a while I see a glimpse of what the web could be if that vision comes to pass. The latest iteration of that is Bookboard. (Sign up here)

Book Board Selection Screen

Bookboard is a web app that was written for the iPad. It makes heavy use of iOS specific features that allow websites to add themselves to the home screen for a full-screen experience and provide specific icons so that to the end user, it kind of feels like an app that just didn’t come from the app store. Even though it’s iOS-specific right now, the UI design is such that it would work across platforms. So many apps, even PhoneGap apps, follow the specific list->detail form that brings a lot of baggage with it. You have to work at making sure your list/detail view works the way it’s supposed to on iOS or Android (or other platforms). But Bookboard has a very design-heavy UI that lends itself to any platform. The books intuitively ask to be swiped from side to side as you are looking through them (with a nice parallax effect in the background) and when you go into the book itself you use the same swipe motions you would expect. It’s list-detail but brought to life in an interactive way.

Reading a Bookboard Book

Bookboard also makes use of hardware acceleration of CSS for many of its transitions. Everything on my iPad 2 is incredibly fluid and it’s difficult to tell that it’s *not* native. One of the things many app developers have to deal with is making their content feel native without it actually being native. The Bookboard approach seems ideal to me. They’re using a UI that hasn’t been replicated by every other app so they get a bit of leeway in terms of performance, but they don’t need it because they’re offloading to the device hardware via CSS. It works out very well.

Bookboard Menu Screen

Beyond the tech side Bookboard is simply a beautiful, well-designed app. It’s meant for children to read (and they can unlock achievements for reading more books) so it has to be intuitive, but it also looks great. Attention to detail like the parallax scrolling add a friendly touch and my daughter loved the app. She knows how to use an iPad and scrollable books, friendly gestures, and words that are magnified on touch all came naturally to her. If you’re a parent with a kid who enjoys reading (or you want them to enjoy it more) Bookboard is well worth a try.

This is how I want the mobile web to look and behave. Bookboard leverages the mobile-app centric parts of iOS to create an app-like experience while still retaining the unique, design-centric approach that has made the web so great. It’s this kind of custom UI and design influence that starts to make developers stop and think about whether they go native or web. A basic list-centric app isn’t that tough to do in native so more often than not, it probably makes sense just to go native. But the kind of custom UI and design that Bookboard uses lets you involve the designers much more deeply in the process. Since most designers (should) feel comfortable with CSS, they can jump in and contribute directly to the end result. If you can get performance like this using web technologies, I think it becomes a tougher sell to try and do native when web gets you more platforms, more reach, more designer input, and more deployment flexibility.

Hopefully in the next couple of years apps will have been replaced by experiences like Bookboard. It would make my home screen a much more interesting and beautiful place while giving developers ultimate flexibility. That’s a big win for the web. I encourage you to go sign up and see what I mean.

Web versus Native Economics and User Adoption

Vibhu Norby has a detailed post on why his startup is pivoting from mobile first to web first. And ultimately it comes down to economics. This has been one of the big problems with the web versus native. In general, it’s been easier for developers to make money with native apps. That ease comes at a price; you’re locked in to a specific platform, and you’re at the mercy of the keepers of that platform. But all-in-all compared to the cheap, throw-ads-everywhere model that has driven the web economy for so long, it was a breath of fresh air. People were willing to give up 30% for access to a new, untapped, and profitable market.

That market still exists, but it isn’t quite the gold rush it used to be. What more people like Vibhu are realizing however, is that you don’t have to choose between throwing a hail-mary on an app store and cheapening your user experience with ads. You can focus on building a great web experience and adding value, charging for that value, and then using mobile as an added touch point to your service. And it turns out that the early process of getting and retaining users is quite a bit less painful on the web.

You have an entirely different onboarding story on the web. You can test easily, cheaply, and fast enough to make a difference on the web. You can fix a critical bug that crashes your app on load 15 minutes after discovery (See Circa). You can show 10 different landing pages and decide in real-time which one is working the best for a particular user. You can also close a viral loop: A user can click an email and immediately be using your app with you. You can’t put parameters on a download link and people don’t download apps from their computer to their phone. Without the barrier of a download + opening the app to try your product, you can prove value to the user immediately upon their first impression, as is with Google. In addition, the experience of signing up for a service is superior in every way. Typing is easier. Sign-up with OAuth is faster. Tab to the next field. Provide marketing alongside sign-up as encouragement. Auto-fill information is a feature in every browser. The open eco-system of the web and 20 years of innovation has solved many of the most difficult parts of onboarding. With mobile, that kind of innovation is lagging significantly behind because we create apps at the leisure of two companies, neither of which have a great incentive to help free app makers succeed.

As a personal example, I have a long Facebook password with lots of random characters. Nothing annoys me more than trying to sign up for anything with Facebook on a mobile app because my password is hard to type, it’s not saved, and I can’t use the key combination I’m familiar with on the desktop. That’s not a good user experience.

There is so much that’s inherently good about the web, as Christian Heilmann eloquently points out, that it’s a shame to think of it last or as a throwaway just because mobile is the new hotness. Since the web has gotten very good at supporting rapid testing and process for getting users on board why not leverage that and then use mobile as just another way for customers to access your web-centric content/services?

Longer term I continue to hope that the good practices from the web will bubble up on mobile devices. From both a core API/feature standpoint and from a user experience standpoint. Once that happens it will become a much easier sell to content creators and developers to go all in with the web and build great web experiences on mobile instead of building native apps that tie back to the web.

Building a Mobile-Themed Slider without jQuery Mobile

I’m generally a big fan of jQuery mobile. I think it’s an ambitious project and it’s got some areas that could be improved, but I’m glad we’re contributing and think it’s going to be a huge boon for mobile web applications as they get bigger and bigger. But building PhoneGap applications with jQuery Mobile is a bit problematic partly because the goal for the project is “Delivering top-of-the-line JavaScript and a unified User Interface across the most-used smartphone web browsers…” and partly because jQuery Mobile can be tough to really customize if you want a specific look and feel. One of the things I wanted for something I’m working on is a slider that is a bit more boxy than the traditional slider used with jQuery Mobile. Some of this might have been possible with customizing the jQuery Mobile theme but I wanted to see what it would take to build my own from scratch.

This example is part of an app that’s using Backbone.js so I won’t post a working example because the Backbone.js infrastructure makes it kind of tough to strip out just the toggle button part. I’ll post the whole thing later, but wanted to show the general process.

The Look and Feel

To set it up I wrapped a div tag around a select tag with a couple of options. The div tag provided the border so it ended up being the track that the sider went along. This makes it pretty easy to customize the look and feel while still being very nicely degraded into a regular HTML select box.

                         <div id="toggle" class="toggleoff">
                         <select name="activetoggle" id="activetoggle" class="selectoff">
                              <option value="all">All</option>
                              <option value="active">Active</option>
                         </select>
                         </div>

Initially both the div and the select start with “off” classes. At this point the CSS starts to take over and create a more slider-looking button. There is a cool -webkit-appearance property that can be used on the slider to give it some instantaneous look/feel. But for the most part I rely on -webkit-border-image to customize the look and feel of the slider button. The CSS for the toggle button itself, the div tag, and the off states give us a basic looking toggle with no real toggle functionality because it behaves just like a regular HTML select box.

Toggle button off state

select {
     -webkit-appearance: push-button;
     margin-top: 0px;
     margin-bottom: 0px;
     height: 50px;
     width: 155px;
     border-style: solid;
     border-color: #cdcdcd;
     border-width: 1px;
     color: #555;
       font-size: 25px;
       overflow: hidden;
     padding-top: 2px;
       padding-bottom: 1px;
     white-space: nowrap;
     text-align: center;
 
}
 
.selectoff {
     -webkit-border-image: url( ../assets/button.up.png ) 4 4 4 4 stretch stretch;
     padding-left: 60px;
 
}
 
#toggle {
     margin-left: 5px;
     margin-right: 5px;
     margin-top: 5px;
     height: 50px;
     width: 312px;
     -webkit-border-radius: 2px;
     -webkit-box-shadow: 0px 1px 3px rgba(0, 0, 0, 0.1);    
     border: 2px solid #cdcdcd;    
}
 
.toggleoff {
     padding-left: 158px;
     background-image: -webkit-linear-gradient(#ffffff, #e7e7e7);
}

I have the benefit of using absolute positioning because I’m building this for an iPhone, but the CSS is pretty straightforward. I’ve got some padding-left properties so I can control how the text looks and where the actual toggle button appears within the div tag. This is why this particular strategy works. When I move between states I’m just going to change the position of the toggle button, I’m not actually doing anything with the select object itself other than changing how it looks and where it is. Here are the “on” classes.

 
.selecton {
     -webkit-border-image: url(../assets/button.down.png) 4 4 4 4 stretch stretch;
     padding-left: 30px;
}
 
.toggleon {
     padding-left: 0px;
     background-image:-webkit-linear-gradient(#bccead, #cbdfba);
}

Just a couple of small changes to gradients and backgrounds so that when our button is on or active, it looks like this:

Toggle button on state

Functionality

Now that the CSS classes are set up I used jQuery to first add/remove the classes I wanted and finally set the value of the select box programatically. As I mentioned, this is using Backbone.js so the code may look a bit odd.

          onMouseDown:function(event){
               event.preventDefault();
               if(this.displayingAll) {
                    $("#activetoggle").removeClass("selectoff");
                    $("#activetoggle").addClass("selecton");
                    $("#toggle").removeClass("toggleoff");
                    $("#toggle").addClass("toggleon");
                    $("#activetoggle").val("active");         
               } else {
                    $("#activetoggle").removeClass("selecton");
                    $("#activetoggle").addClass("selectoff");
                    $("#toggle").removeClass("toggleon");
                    $("#toggle").addClass("toggleoff");    
                    $("#activetoggle").val("all");                             
               }

My Backbone view has a variable, displayingAll, which I set to either true or false depending on what is currently visible. It helps track which classes need to be added/removed. But the first, and probably most important thing, is that I’m capturing the event and keeping it from doing anything. I don’t want the default select behavior at all so I can trap it and make sure it doesn’t keep doing the rest of its work. That means no pop up where the user can select values. Instead I go through and swap out the on/off classes to change the look of my button. Finally I use the val() method to set the value of the select so that what the screen is showing is the actual value of the select input.

So now the slider is working but we haven’t done any animation. So right now the slider just jumps back and forth. It works but it isn’t all that pretty. Luckily CSS3 is pretty awesome and we can leverage the very powerful -webkit-transition to help us out.

Animation

Animation for this example is insanely simple. Using the -webkit-transition CSS property we can listen for changes in the DOM on a specific property and whenever that property changes we can play a specific transition. The way I have set this up is that I’m changing the padding-left property between on/off classes so that’s the one we have to listen for.

Quick sidenote: I struggled with this for a bit. At first I was using the align property of the div to move the toggle button back and forth. That had the benefit of being able to scale better for multiple pixel-widths. The button would move back and forth just fine but there wasn’t a way to animate the align property that I found, which makes sense. So to do animation I had to use a value that could be animated and padding-left ended up being a decent option.

In order to get the animation to trigger we have to add a single CSS property to the #toggle div tag:

     -webkit-transition: padding-left 250ms ease-out;

So whenever the padding-left property changes (on a Webkit browser) a quarter of a second ease-out transition will play and move the toggle button back and forth. Under the hood we’re changing the value of the select so that if we have to rely on that value it’s all in sync while still creating a very specific look-and-feel for our toggle button.

I realize this isn’t entirely helpful without a working demo and I’ll work on getting a jsFiddle or something up to show it but I’m working on some other bits of the project and want to be able to share the whole thing when it’s done. One of the main things I learned: CSS3 transitions aren’t entirely intuitive when coming from the Flash world, but they’re very powerful.

Passing Data Between Pages in jQuery Mobile

Coming from Flex one of the things I’ve struggled a bit with is passing data between views in my jQuery Mobile applications. The template approach with Mustache worked really well, but it also had a lot of overhead. In fiddling around today I found a more hacky way that seems to work pretty well (though I think the Mustache route is still better). It relies on the fact that the pagebeforeshow method provides a prevPage property as part of its data object. That prevPage property is just a representation of everything in DOM of the previous page. That means it’s relatively easy to use selectors and that object to pass data to the new page.

The setup of my pages is as follows. My first page has a list of breweries, and each brewery page has a list of the beers that brewery uses. When you click on any of the beers, it goes to a form that can be used to rate the beers and provide some extra information about them. My goal was to prepopulate some of those forms with the beer data I already had. For instance I know the beer name, brewery, and style of each beer, so I should be able to prepopulate those, but they change for every beer so it has to be dynamic.

Within each page I defined a hidden div with two span elements with ids that represent the brewery name and brewery location (since they’re the same for every beer). Then within the beer list I have a hidden div that contains the beer name and the beer style. Here’s an example:

<div data-role="page" id="aleasylum" data-theme="e" data-add-back-btn="true">
     <div data-role="header">
          <h1>Ale Asylum</h1>
     </div>
     <div style="display:none">
          <span id="brewernameinfo">Ale Asylum</span>
          <span id="brewerlocationinfo">Madison, WI</span>
     </div>    
     <div data-role="content">    
          <ul data-role="listview">
               <li data-role="list-divider">Year Round Beers</li>
               <li>
                    <a href="#beerdetails">
                         <img src="images/hopalicious-thumb.gif" />
                         <h3>Hopalicious</h3>
                         <p>5.8% abv. Eleven separate additions of cascade hops give this American pale ale its lush citrus aroma and bold hop flavor without crazy bitterness. Hopalicious is available year round in six packs and on tap throughout the Madison and Milwaukee regions.</p>
                         <div style="display:none">
                              <span id="beernameinfo">Hopalicious</span>
                              <span id="beerstyleinfo">IPA</span>
                         </div>
                    </a>
               </li>
               <li>
                    <a href="#beerdetails">
                         <img src="images/madtown-nutbrown-thumb.gif" />
                         <h3>Madtown Nutbrown</h3>
                         <p>5.5% abv. Our nutbrown ale is velvety smooth with a rich caramel aroma. We blend seven different malts for just the right touch of sweetness and a creamy finish youÔøΩll really dig. Madtown Nutbrown is available year round in six packs and on tap throughout the Madison and Milwaukee regions.</p>
                         <div id="info" style="display:none">
                              <span id="beernameinfo">Madtown Nutbrown</span>
                              <span id="beerstyle">IPA</span>
                         </div>                        
                    </a>
               </li>

So in order to grab that, I just added an event listener to the pagebeforeshow method that uses selectors to grab the data. One of the critical parts is that jQuery selectors have an optional context property that can be set so that jQuery only selects from that context. In this case, since my pages are all using the same id names for the values, I need to set the context so that the selectors are only pulling from the previous page and not the entire document.

 $('#beerdetails').on('pagebeforeshow',function(e,data){
     var beername = $('.ui-btn-hover-e #beernameinfo',data.prevPage).text();
     var brewername = $('#brewernameinfo',data.prevPage).text();
     var brewerlocation = $('#brewerlocationinfo',data.prevPage).text();
     var beerstyle = $('.ui-btn-hover-e #beerstyleinfo',data.prevPage).text();
     $('#beername').val(beername);
     $('#brewername').val(brewername);
     $('#brewerlocation').val(brewerlocation);
     $('#beerstyle').val(beerstyle);
 });

The code above executes before anything gets displayed on the new page, grabs the values from the first page with the hidden div tags, and then sets some of the form fields to those new values.

It strikes me as a bit odd that there isn’t an easier way to do this, so it could be that I’m just not googling the correct thing and jQuery Mobile has something built-in to help with this issue. It does seem like this can be done by using URL variables, but what I like about this approach is that it’s a bit more semantic and there’s no required parsing of the URL string.

Flash Player 11, AIR 3, and Flex/Flash Builder 4.6

Today is a pretty big day for Adobe developers. We’re officially announcing Flash Player 11, AIR 3, and Flex 4.6 and Flash Builder 4.6. The bits will be available in early October, but we’re announcing things today to help provide developers with information on what’s coming. I’ve been at Adobe for 4 years now and it’s been a very interesting 4 years as the landscape has evolved. It’s definitely been an up and down ride for Adobe developers, but the world has never been a better place for interactive developers, and these set of releases provide a ton of functionality aimed at helping Adobe developers create content in the most cutting edge places.

Gaming

We’ve been doing a lot of work to help enable console-esque games on top of the Flash Platform. Flash Player 11 includes Stage3D, which is going to open up a whole new world for game developers. Zombie Tycoon and Tanki are initial examples of what can be done and I can’t wait to see what comes of it. I’m reminded very much of the early days of Flash where a bunch of creative people were given a technology that was pretty open-ended and poked and prodded to create a bunch of very cool things. I think we’ll see that kind of revolution with Stage3D because of the ubiquity of Flash and the creativity of our developer community. Also in the gaming bucket is a framework we’re working on called Starling, which leverages Stage3D to create a super-fast way of doing parts of 2D games. It’s a great merger between the underlying technology/performance benefits of Stage3D and the kinds of things people want to do in 2D games. I think it’s also going to see some traction beyond games as agencies start to use it to enhance 2D content.

Mobile Applications

Flex and AIR have really found a great place in mobile applications. The performance enhancements in 2.7 made building native-experiences with AIR possible and we’ve seen some great examples of that in action including Machinarium and Caltrain Times. I’ve been impressed with performance on my 100 Days of Exercise application on iOS. I’m incredibly, incredibly excited by what this means for Flash. There’s a definite need to create mobile apps that can be deployed to multiple application stores. The Flash Platform provides a way to create great looking, high-design applications with near-native performance that can run on multiple devices. That’s a big deal.

And this release of AIR 3 goes where we haven’t gone before on the Flash Platform with native extensions. Now if there are features that aren’t included in AIR, like access to a credit card reader, you can build those extensions in native code and then link them to your AIR applications and leverage those libraries. It’s a great mix of native for specific use cases and AIR/Flash for fantastic user interfaces. It’s a big, big, big deal to be able to extend the platform and it’s a huge step.

I also think we have one of the best mobile-tool chains out there. Flash Builder 4.6 is going to help with creating those native extensions while also enabling the use of captive runtime in AIR so your applications don’t need to rely on the external AIR runtime on Android. Combine that with the enhancements that are coming in Flex 4.6 and it adds up to a world class mobile development platform that lets you reach more devices that matter. Flex 4.6 is especially exciting because of the new components that have been added. Flex and AIR are far and away the best toolset for interactive developers or any mobile developer who needs to create content for multiple devices. The apps you can build with Flex and AIR are going to stand out from the boring, standard apps that have started to litter app stores. Creativity will win the day and creativity is at the core of Flex/AIR.

Beyond

So this is a huge release, and I’m excited. But I’m also excited about the future of Adobe and how we are responding and will continue to respond to the evolving marketplace. As Danny Winokur, VP and GM of the Flash Platform, said recently:

“We’re not so concerned about what the right technology is for that as long as we’ll be able to deliver those experiences. We’re working with Microsoft and other members of the HTML community including Google, Apple, and others to enable rich experiences on HTML5.”

This is not a technology war. Adobe is about enabling developers to build the best possible experiences with the technology they want. We want to build tools and services that cater to that ethos. That takes the form of cutting-edge gaming features like Stage3D and world-class mobile app features with Flex, AIR and Flash Builder. But HTML5 is exciting for a lot of reasons, and Adobe will help developers there as well. If you’re an interactive developer, the future is very, very bright for you.

So you better get a good pair of sunglasses.

Dismissing a Flex Mobile PopUp With the Back Button

In an application I’m building for Android I use a lot of pop up windows (because that’s how Android does combo boxes) and I was having a tough time figuring out how to get them to close when the user pushes the back button. By default, the framework will call navigator.popView() whenever the back button gets pushed and the only way to override that is by doing it at the application level, which isn’t really ideal.

So here’s what I came up with.

Basically I intercept the removing event on the view, which is the last event that gets called before the view goes away. Using that event I check to see if any of my PopUps are on the screen using the isPopUp property and if they are, I use event.preventDefault() to stop the view from being removed and instead just remove the PopUp.

protected function view1_removingHandler(event:ViewNavigatorEvent):void
{
     if(exerciseList.isPopUp)
     {
          PopUpManager.removePopUp(exerciseList);
          event.preventDefault();
     }
 
     if(timeList.isPopUp)
     {
          PopUpManager.removePopUp(timeList);
          event.preventDefault();
     }
}

I’m not sure if this is really the best way to solve this issue, so if anyone has something that they’ve done I’d love to hear about it in the comments.

Beer List for Flash Camp 2011

Most of you know that I’m a pretty serious beer person. And since we have a fantastic beer store, City Beer, just up the street from the SF office, it makes it easy to get good beer for events like Flash Camp. I just finalized the list and we’ve got some great beers. At this point you should have no excuse; it doesn’t get better than mobile development and great beer.

We’ve got some great sessions, the product teams are coming to help answer questions, and it will be a lot of fun to show off the Flex mobile story in person.

The Implications of Every Flash Developer Being a Mobile Developer

There’s an article in the Wall Street journal today about the demand and insufficient supply of mobile developers, which is becoming a huge problem for companies as mobile strategy becomes more and more critical. One of the main problems, as the WSJ draws out, is that these mobile platforms are relatively new so it’s tough to find developers with a lot of experience. Many companies are turning to good developers and retraining them as mobile developers to fill demand.

If a software engineer doesn’t have mobile experience, the company has sometimes been willing to spend several weeks training the engineer to work on mobile platforms, Mr. Rosenthal said.

Given the mismatch between supply and demand, many companies say they have no choice but to retrain software engineers in the art of mobile development. In the last year, Major League Baseball’s Internet company MLB.com nearly doubled the number of mobile engineers it has to 19, said MLB.com CEO Bob Bowman.

I thought this article was a perfect complement to the announcement this week of Flash Builder 4.5 and Flex 4.5, which are focused explicitly on helping Flex developers build applications for mobile devices like iOS, Android, and the PlayBook. There is obviously huge demand for mobile applications, and because of scarce supply and experience, existing developers are going to have to think about how they can gain mobile experience. Flex mobile does a fantastic job of making that learning curve smaller by letting Flex developers use what they already know and providing some key mobile features (like ViewNavigator for managing views, the ActionBar for managing global navigation, etc) so that they can quickly turn out Flex applications for these mobile devices.

If you’re a Flash or Flex developer, then with AIR for mobile devices and Flex 4.5, you’ve got the skills to go out and build applications for the biggest platforms. That’s a huge advantage to you as a developer and for any developer who doesn’t want to get locked into a specific platform. As the chart below shows, there are a lot of people looking for experts in iPhone, Android, and BlackBerry, but there are a lot more people who are looking for Flash experts. With this release, you get the best of both worlds.

Presenting at the Portland Adobe User Group January 20th

PDX RIAI’ll be doing a presentation on the very diverse world of mobile and the Flash Platform at the Portland Adobe User Group on January 20th. I’ll be covering the iOS Packager for Flash Professional, Flex Mobile, AIR for Android, and the RIM tablet. It’s going to be a mix of hello world samples so that you can see the workflows as well as some techniques I have found for optimizing applications to get the best performance out of your apps. It will probably focus mostly on RIM and Flex Mobile/Android because that’s what I’ve spent the most time on.

So if you’re in Portland, come out and join us. I’m hoping to be able to answer any questions people have about building mobile apps with AIR and Flash, so if you’ve got questions, come armed with those as well. It’s also my birthday so we’ll be finding a place to grab beers and geek out afterwards (it is a PDX RIA meeting after all).

Slides and Demo for ‘Intro to Flex “Hero” Mobile’ Presentation at SDFUG

I had a blast presenting at the San Diego Flash Users Group last week and getting a chance to show off Flex “Hero”‘s mobile features as well as getting to hang out with the SDFUG crew. Big thanks to Chris Griffith and Kyle Tyacke for setting it up and to Andrew Walpole, Aaron Pederson, and James Polanco for the great beer opportunities.

I got a chance tonight to upload my slides to Slideshare. They can be found here and embedded below. You can also check out the demo app I built, which shows off some of the things I talked about in the deck. It’s here on Github.