Friday, July 27, 2012

Beginning jQuery Mobile Talk

I will be giving a talk to the jQuery LA Meetup group, on Beginning jQuery Mobile development on Tuesday, August 28th, at 7PM. Whether you are just curious about mobile development or about to begin a new project using jQuery Mobile, you will want to attend this presentation. 

I have been using jQuery Mobile for over a year now and I will reveal all the tips, tricks, and hard fought knowledge I've gained from building KBB.com's mobile site, http://m.kbb.com.   



Plus for all of the designers out there, I will also show how to use the ThemeRoller to make your site unique and avoid the cookie cutter look.


And I will give away all of the source code for all the examples I will present. 


For more information, please check out jQuery LA's site at: 


http://www.meetup.com/jQuery-LA/events/61883862/

Safari Online Blog Posts


I've done a series of guest blogs for Safari Books Online. The topic linking them all is jQuery Mobile. The subjects are: 

  1. Combine jQuery Mobile and iScroll 4
  2. jQuery Mobile Performance Improvements
  3. jQuery Mobile Debugging Tips

But don't fear fellow coders, I will have some tasty new post coming early next covering both jQuery Mobile and PhoneGap. Here are the links to the articles for Safari Books Online: 


The first two posts on the list above made Safari Books Online Top Ten Blog Posts of 2012: Safari Books Online, Woo hoo!

Saturday, July 21, 2012

jQuery Mobile Performance Improvments

Here is the another guest blog for Safari Books Online. This one is on improving the performance of your jQuery Mobile apps.


jQuery Mobile Performance Improvement

Friday, July 20, 2012

PhoneGap Day

I am have been in Portland since Tuesday night for OSCON 2012. Today I will be hanging with the PhoneGap team for PhoneGap Day. Looking forward to hearing what will be in version 2.0. If you are there be sure to say, "Hi."


For more info about PhoneGap Day.

jQuery Mobile: Live Demos

Android Emulator
While having the complete source code for an app is extremely valuable, being able to see a working version  of it also helps. For that reason I have many of my jQuery Mobile tutorial apps available on my Demo site.

Each of the examples is intended to run from a smart phone or from either the iPhone Simulator or the Android Emulator (left). If you lack any of those options, I would highly recommend either the Opera Mobile Emulator or Chrome with the Window Resizer extension.

So please try the demos. You can find the source code for all of them on my GitHub Repo.
Opera Mobile Emulator
Chrome with Window Resizer

jQuery Mobile and iScroll

I've done a guest blog for Safari Books Online explaining how to pair jQuery Mobile and Matteo Spinelli's iScroll 4 together. The results is smooth interior scrolling between the header and footer by just swiping your finger across the screen. It works in either vertically or horizontally and gives your mobile site a very app-like feel. Here is the link to the article: 
jQuery Mobile Scrolling.

The source code for the article is on my GitHub site at:
JQMScrolling

A live demo is also available at:
jQuery Mobile & iScroll 4 demo

Sunday, July 15, 2012

JQM Skeleton Update



This is the second version of this post. I realized late that version 1.1.1 of jQuery Mobile had been released three days ago. Since it fixes a lot of issues, I made corrections to the post and the source code to support it.


The JQM Skeleton project has been updated with a few niceties to make it friendlier to mainly to iPhones, but it also helps Android phones.

jQuery

The first thing that I changed was the jQuery Mobile plugin from version 1.1.0 to 1.1.1. I just released this version went final. This fixes a lot of issues, especially for the PhoneGap lovers out there.

Apple Web App

We already had the meta tag for supporting Apple’s web app functions set to true. In order to make most use of it I also added support for the iPhone and iPad variety of icons. The icons are a big nicety for your users since if they add your site to their home screen, it will give them an icon which looks like any other app on their screen. In the same vein, I added support for the iPhones start-up image. This is a splash page which if it exist on your site and your site is home screen’ed, will be downloaded to the user’s phone. When the user launches your site next, the splash page is shown while your site is downloaded to the user’s phone. All of these modifications, make your site very app-like to your users.

One interesting thing for Android 2.2 and higher users is that the home page will also read Apple’s apple-touch-icon attribute and use the big icon file on the home page instead of either favicon.ico or the generic star icon. Android will even give it rounded corners.

Favicon.ico

I added favicon.ico to the root directory and I also added a link to it in the <head> section. While most browsers will pick it from the root, the link helps ensure that it is found.

Summary

That’s it for this update. There will be another one in a few weeks as I put more support for the iPad in it, plus a few other things that I am playing around with now. The source, as always, is on GitHub: https://github.com/Rockncoder/JQMSkeleton.

Wednesday, July 11, 2012

jQuery Mobile & iScroll: Image Scaling and Panning

jQuery Mobile & iScroll: Image Scaling and Panning

Just like the regular web, mobile web apps need to work with images. Common wisdom says that you should optimize images for mobile web apps, but what does that mean? What looks good on my Nexus One isn't going to look to hot on my iPad. The reality is that you are going to have to scale images for the user's device. But what if the user wants to see the image in all of its high resolution glory? This where panning comes in. The question is, "How do you pan an image on a mobile device?
One solution is to use iScroll 4. Written by Matteo Spinelli, iScroll 4 is a JavaScript plugin which uses CSS3 transformations to smoothly move DOM elements. For more information about how iScroll 4 works please visit Matteo's site.


The demo app consist of two pages. The first page shows the image scaled to fit the display. During its pageshow event handler it dynamically sizes jQuery Mobile's content area. It then uses these dimensions and HTML to scale the image. If you only supply one dimension of an <img> tag, HTML supplies the other and maintains the image's aspect ratio.
The second page instantiates an iScroll object during the pageshow event handler and destroys it in the pagehide event handler. The magic of the iScroll is in the CSS, basically there is a viewport called 'wrapper', which is sized to the content area of the jQuery Mobile page. Nested in the viewport is the total viewable image, which is named 'scroller'. The size of the scroller is determined dynamically using jQuery’s dimension methods to measure an unscaled and hidden version of the image named 'hiddenPic'. Please note how the hiddenPic is not on any jQuery Mobile page and is taken out of the HTML flow.


Unfortunately for all of the Windows Phone 7 fans, iScroll 4 is not compatible with it. I don't if this will change in the future, but for now this code is not a solution for WP7.
iScroll 4 combined with jQuery Mobile gives mobile web apps the look and feel expected only of device apps. In a future tutorial I will throw PhoneGap into the mixed. The code for this tutorial is on GitHub.

jQuery Mobile, PhoneGap, and the Camera Device





















One of the great promises of PhoneGap is it ability to access a device's hardware from an easy to code, web-style development environment. In this tutorial we will show how to the device's camera, capture an image, scale it, render it to a page. This tutorial is for iOS, but it should work across devices.

The code in app.js is roughly divided into three parts. The core level Kernel code which dispatches jQuery Mobile events. This code has already been explained in the jQuery Mobile Skeleton Tutorial. 

Next is the Dimensions code. This object consists of two methods, one which dynamically determines the dimensions of the jQuery Mobile page content area. The second which returns those dimensions.

Finally is there is the page code. It has only two externally accessible methods, the handlers for the "pageshow" and "pagehide" events. Most of the app's logic is inside of the "pageshow" event handler. 

Since this is an immediate function, it is executed when the JavaScript parser first encounters it. At that time it caches a few jQuery selectors. This is a performance enhancer since DOM traversal can be time consuming.

Once a "pageshow" event occurs, it calls the Dimension code. It is important to wait for this event since it indicates that jQuery Mobile has rendered, which is necessary for us since when need to determine the size of the header and footer. We use the size of the content area to set the size of the "#picFrame".

The last thing the "pageshow" event handler does is to bind a tap event handler to the "Snap!" button. Inside of the event handler we call PhoneGap's navigator.camera.getPicture() method. Also we do a performance enhancers here as well. I know that event.preventDefault() and return false speed things up by keeping unnecessary code from executing. I am hoping the event.stopPropagation() will also help.

We also bind an event handler to the onload event of the <img> element. When this event is triggered, we use it to get the width and height of the <img>. We then use HTML to scale the image for us. By setting only dimension, HTML will automatically "set" the other for us and maintain the aspect ratio.


That's it for this tutorial. I planned to do at least one more exploring the camera. As always the code for this tutorial is on my GitHub account.

iOS PGCamera on GitHub

For all of you Intellij IDEA fans out there, like me, an Android version of the code available. The HTML/CSS/JavaScript is identical to the iOS version, only the wrapper changes.

Android PGCamera on GitHub





Sunday, July 8, 2012

Android, Intellij IDEA and PhoneGap: Getting Started


An update to this post covering Intellij IDEA 12 CE is located here.

A few months ago I wrote a review of JetBrain’s WebStorm IDE, which is my new favorite IDE. Yet even after discovering WebStorm, I continued to slog through Eclipse for Android apps. Well WebStorm has a Java clone, IntelliJ IDEA. And it is way better than Eclipse. It isn’t that Eclipse is a bad IDE. It is just that IntelliJ IDEA is so much better than it. Even running on my quad-core Macbook with a SSD drive and 8 GB of RAM, Eclipse felt sluggish, but IntelliJ IDEA feels like I have the afterburners on full.

The main problem with using IntelliJ IDEA is that most Android stuff assumes that you are using Eclipse and it takes a bit of poking around to figure out how to do the something in IntelliJ IDEA. Case in point, PhoneGap. All of the tutorials I’ve read so far, and ones that I have written, are for Eclipse. Well here is how to get the PhoneGap, hello world app running in IntelliJ IDEA. This tutorial was written for the Mac version, but from what I can tell from JetBrains website, the PC and Linux version are nearly identical. 


Big thanks to the PhoneGap team, this tutorial borrows heavily from their Getting Started with Android page. For more information about IntelliJ IDEA please visit JetBrains website.



  • From the IntelliJ IDEA start page click Create New Project

  • On the New Project dialog box
    • Select Create project from scratch
    • Then click Next

  • In the Project name: type HelloCordova
  • Select type: Select Android Module
  • Click Next

  • Select Create source directory, make sure the relative path is src
  • Click Next

  • Make sure that Android SDK: shows Android SDK
    • If not use the ellipsis button to set the location of your Android SDK
  • Make sure that Application is selected and that all of the settings are correct for your needs
  • Click Finish

  • IntelliJ IDEA will now create your application
  • Create a new subdirectory of the /assets directory: www
  • Copy cordova-1.9.0.js to the directory /assets/www
  • Copy cordova-1.9.0.jar to the directory /libs
  • Copy the entire xml directory to /res

  • Right-click cordova-1.9.0.jar and click Add as Library...Make sure that:
    • Name: cordova-1.9.0
    • Level: Project Library
    • Add to module: HelloCordova
    • Click OK

  • Edit the MyActivity.java file
    • Add the following import: import org.apache.cordova.*;
    • Replace the class’s extend from Activity to DroidGap
    • Replace setContentView()
      with
      super.loadUrl("file:///android_asset/www/index.html");


  • Open the AndroidManifest.xml
  • Paste the following between the <uses-sdk.../> and <application.../> tags

<supports-screens
   android:largeScreens="true"
   android:normalScreens="true"
   android:smallScreens="true"
   android:resizeable="true"
   android:anyDensity="true" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.BROADCAST_STICKY" />


  • Paste the following inside of the <activity.../> tag

android:configChanges="orientation|keyboardHidden"

  • Your AndroidManifest.xml file should look like:


  • RIght-click the www directory
  • Hover over New, the click HTML File
  • In Name: enter index
  • In Kind: select HTML5 file
  • Click OK



  • Paste following code into the file:

<!DOCTYPE HTML>
<html>
<head>
<title>Cordova</title>
<script type="text/javascript" charset="utf-8" src="cordova-1.9.0.js"></script>
</head>
<body>
<h1>Hello World</h1>
</body>
</html>

  • Deploy your app to the emulator by clicking the Run selected configuration button, the green triangle next to the drop down which should say HelloCordova



And that’s it. In a short while your app should start running on the emulator. Hey if you like 



Monday, July 2, 2012

PGCompass: PhoneGap Compass

It is very easy to read the compass device in PhoneGap. When you combine it with a png file and a bit of CSS3 you can quickly build a nice looking compass similar to that built in on the iPhone and other devices.

All of the magic of the compass is contained one simple function:

watchId = navigator.compass.watchHeading(success, error, [options])

This call sets up two functions, one to receive a successful callback, the other to receive an error callback, and finally some options, the only one truly supported is the frequency in milliseconds.


If the call is successful it passes back a heading object. It can contain several properties:

  • magneticHeading
  • trueHeading
  • headingAccuracy
  • timestamp

The property that we are interested in is the magneticHeading. While trueHeading may seem more attractive it is not support on Android, so I choose not to use it. 

In the example code, I implement publisher/subscriber pattern for handling the success callback. It may be a bit of overkill, but I like the separation of concerns it gives me. One listener handles the updating of the degree text, the other rotating the compass face. This is accomplished using a CSS3 transform on the <img> tag holding the compass face.

One thing that we should do, but are not is to stop the watcher. This is relatively easy to do. The watchId that is returned from the watchHeading method is simply passed to another method:

navigator.compass.clearWatch(watchId);

This will turn off the listener. That is it for this quick tutorial. The code is on GitHub. Next up everyones favorite device, the camera. I will show how to take a picture and manipulate the image in PhoneGap. Until then, happy coding.

PGCompass Source Code on GitHub