Friday, February 28, 2014

Using Google Fonts in a PhoneGap App


Want to use Android's Roboto Font? Check this post.


Often we developers under-estimate the value that a proper font adds to the look and feel of our apps. We are usually OK with using the system font. The problem with doing this in a PhoneGap app is that the system font can look very different from one device to the next, heck it is can be different from one version of the operating system to the next, like the change from iOS 6 to 7. So simply depending on the system font may not be a good idea.

Fonts, like anything of value, are not free. While they can be reasonably priced, if you are an indie developer even the most reasonably priced font can seem expensive. Luckily there is Google Fonts. Google has gathered a great collection of free to use fonts. Now normally you would simply link to these fonts in your web site and be done with it. You could do this in a PhoneGap app also, but that would not be an ideal user experience. A PhoneGap app should not be overly reliant on the Internet and the precious milliseconds it takes for the font to download to the user's device may be too much for many users. But you can download the font and embed it in your application. That way you can have a good looking UI which is also fast.

Google gives us three different ways to access a font from the Internet: <link>, @import, and JavaScript, but no way to directly download it. So I am not sure if this is kosher, but I can't think of a logical reason why it would not be. 

1. Select your font
The first thing that you need to do is select your font. Head over to Google Fonts. Type the name of the font type or style that you are interested in. Once you have found the font, click the "Add to Collection" button. Then click the "Use" button located in the lower right hand part of the page. Then choose your styles and extra character sets that you may need. 


2. Get the @import info for your font
Scroll down to the "3. Add this code to your website:" section and click the @import tab. Copy the URL from the @import statement be sure to include the entire link including "http://" up to the but not including the closing parenthesis.


3. View the download code
Copy the URL to your browser and hit return/enter. In Chrome this show the @font-face statement page in the browser. I am not sure if this will work the same in other browsers, if it doesn't please try it in Chrome. From here you need two things: the statement itself and the URL for the actual font. Copy the URL from the "src:" line to another browser tab. Be sure to include everything from the "http://" up to the ".woff" extension.


4. Download and rename the font
Paste the URL into the another browser tab and press return/enter. This will cause the font to download to your computer. At this point it will have really long and funky name. I suggest changing the name to something more human friendly like the name indicated by the local attribute of the "src:" line.

local('SourceSansPro-ExtraLight')

5. Add the font to your app
Now copy the font into your app. I usually put all of my fonts together in a font directory. 

6. Add the font to your CSS
Add the font to your CSS file. The @font-face statement gives us all of the information we need for the CSS file. Copy all of the information from the @font-face page to the top of your CSS file. Remove the local attributes from the "src:" line and change the URL so that it is a relative path to your font file. Mines looks like this:

    src: url('../font/SourceSansPro-ExtraLight.woff') format('woff');

Here is a screen shot of my CSS modifications and my apps directory layout:


Summary
The screen shot at the top of the article shows how my app, which is a PhoneGap clone of the iPhone calculator looks with the addition of the Google Font: Source Sans Pro - Extra light. The one below shows how it looks without any font specified. I think it makes it look a helluva lot better.




Saturday, February 22, 2014

Removing Obsolete "Cordova-based (pre 2.0)" template from Xcode


If you are a long-time PhoneGap developer like me, you may have missed a release note somewhere like I did. When PhoneGap released version 2.0, they dropped support for Xcode templates. While that sounds like a bad thing, it wasn't. The templates never seemed to live up to their promise, plus it probably wasn't easy trying to keep up with all of the changes that Apple kept making to the internal plumbing of Xcode. 

The problem for me was that I wasn't sure how to get rid of the Cordova template. Now it was harming anything it was just minding its own business but for some reason or another it bugged me. I had to get rid of it.

Luckily it is easy enough to remove a template. Before you do what I did, a word of caution. I am not sure if this is proper way to do this. It seems to work fine on my machine, but don't blame me if it doesn't work for you. Be sure to backup your system before you proceed.
  1. Launch Terminal
  2. Change directory to the Xcode templates:
    1. cd "Library/Developer/Xcode/Templates/Project Templates/Application"
  3. Delete the directory holding the Cordova template:
    1. rm -rf  "Cordova-based (pre 2.0) Application.xctemplate"

Please be careful with the rm command with the -rf options. It will delete a directory and all of its contents without further prompting. 

Once you re-open Xcode, the old Cordova template will be gone and you can relax and get back to coding. 

Tuesday, February 11, 2014

PREVIEW: WP8, PhoneGap 3.0+ and Twitter API 1.1 - part 1.5: User Timelines


In my next post I will show how to make the Twitter API v1.1 client run on Windows Phone 8. Once again we will use ChocolateChip-UI to get that great WP8 look and feel. Porting this will be so easy it make you wonder why you haven't ported all of your PhoneGap apps to WP8.


For those of you who can't wait, go ahead and start with the code the code from this post: PhoneGap 3.0+ and Twitter API 1.1 - part 1: User Timelines. All you need to do is add a platform for wp8 and then build it. Seriously that's all, but in the post I will do it all step by step.

Take care,

Troy

Sunday, February 9, 2014

PhoneGap 3.0+ and Twitter API 1.1 - part 1: User Timelines


Want an easy PhoneGap app? Check out this post.

In a previous post I showed how to use Twitter's application-only authentication to gain access to a user's timeline via API version 1.1. Now it is time to show some love to my PhoneGap friends as well. Here is the complete code to access a user's timeline. This tutorial is also a multi-parter. Part one displays a user's timeline. Part two: shows how to do a Twitter search, similar to an older post. In both, we will use app-only authentication and use ChocolateChip-UI for our looks.


YOU WILL NEED YOUR OWN CONSUMER KEY & SECRET!

I want to say that up front to hopefully stop people from complaining that the app doesn't work later. Getting a key and secret is easy and free so there is no good reason for not getting one. The app doesn't have a working key or secret. It will build, but it won't run until you replace the mock key and secret, with real ones. 


Getting Your Own Consumer Key and Secret
  1. Simply go to https://dev.twitter.com
  2. Click the "Sign in" link in the upper right hand corner
  3. Enter your credentials and click "Log in"
  4. Hover over your avatar in the upper right hand corner
  5. Click the "My applications" link
  6. Click the "Create a new application" button 
  7. Fill out the application details
  8. Accept the "Developer Rules of the Road"
  9. Complete the captcha
  10. Click the "Create your Twitter application" button
  11. On the "My applications" page, click on your application's name
  12. Your consumer key and secret will listed in the OAuth settings section




Keep your consumer key and secret secure. Don't do anything foolish like publish them in a tutorial.

Same-Origin Policy

Before we really get going, I need to address a question I frequently get asked: How can you access Twitter's API from a PhoneGap app? Aren't you restricted by the browser's same-origin policy? The answer is no. While PhoneGap apps run in a web view, they aren't delivered by a web site, they are served from by "file://". So when you see jQuery making requests of third party sites, like Twitter, don't freak out. The restrictions on making cross site requests was never on jQuery or XHR it was on the browser.

Parts is Parts

In the JavaScript world there are no standard libraries, so using other people's code is crucial to being a proficient developer. In this tutorial I use six open source libraries besides cordova itself. At the base of things is jQuery 2.0 it is indispensable tool and two of the other libraries require it.

Underscore and Backbone go hand in hand. I prefer to work with Backbone because I like the way it handles collections and views. It helps keep things conceptually neat in my head. Underscore is required by Backbone and make processing the collection easy.

Moment.js is one of my favorite libraries. Today's mobile is all about timeliness. People want to know when something happen not simply what happen. Both Twitter and Facebook display time in normal people speak. They state, "5 minutes ago", "2 hours ago", "3 Months ago", etc. This is much easier for the brain to digest than Jan 15 2014 11:00:22. Moment does a lot with time including display it in how long ago fashion.

The code for the base64 encoder comes Chris Warburton via his repo on Gitorious. Your consumer key and secret must be URL encoded, combined together, then base64 encoded.

The final library is ChocolateChip-UI. It is a relatively new for me and I am still learning it. There are somethings I don't like about it but one thing for certain is the look and feel of it is amazing. Most people don't realize they are looking at a PhoneGap app. And equally awesome that it looks like an iOS app on Apple devices and looks like an Android app on Android devices. The magic is all in the CSS file. There is one for iOS, one for Android, and even on for Window Phone. The app in the tutorial on supports iOS and Android, but I will add Windows Phone later. 

Getting Tweets

I use a backbone collection named tweets.js to get the tweets. In fact most of the heavy lifting happens in this file and its associated view. The best place to begin decoding the collection is with the initialize method. Backbone will automatically call the initialize method of a collection when the object is instantiated. Once called I create a deferred object to represent the state of the authorization. This necessary since the ajax call to get authorize happens async. Once the deferred object resolves, we fire an event to let the rest of the app know. Be sure to replace the urlApiKey and urlApiSecret with your own key and secret. THE CODE WILL NOT WORK WITH OUT.

In router.js the app kicks off properly with the method rnc.resolver.initialize. Most of my PhoneGap apps have this function. Because I am using jQuery with PhoneGap there are two things which need to happen before my app is in a functional state. PhoneGap must throw the device ready event and jQuery must throw the document ready event. I have seen lots of people write code which doesn't wait for one or the other and most of the time things still work, but occasionally things act strangely and in unpredictable ways. This is usually a result of not waiting. I use a deferred object to sync up the two events and call my initialize method. This ensures that my app is in a runnable state.

Once the authorization event fires, I fetch the collection. I tweak the sync method of the collection to work with Twitter's API. Backbone collections by default work with RESTful APIs. Note that I only implement the get method since can't write, update or delete tweets. Before you ask, I only want to read tweets with this app. Once the tweets come back from twitter, I do a bit of parsing just to ensure that I got some data, then I return the array of tweets. 

With the collection full of tweets we display them in the view, listings.js. This view is relatively straight forward. In its initialize function it hooks an event which, route:listings-article, it is triggered in router.js and indicates that this page has been activated. The render method spits out mark-up and the show method places the rendered markup on the page. 

Note: the render method uses Underscore templates to render the contents of the tweets collections as HTML. The template is stored on the index.html page as "tweets-template". 

Android or iOS

In order to get the correct look and feel for each platform I use the merges directory. In it I create a CSS folder for each platform and place the appropriate copies of "chui-3.5.0.css". Chocolatechip-UI names the Android and iOS version: "chui-android-3.5.0.css" and "chui-ios-3.5.0.css" respectively. I rename both to "chui-3.5.0.css". This way when PhoneGap builds the platform it grabs the platform specific file. 

Summary

This is it for this post. This code is not ready for prime time. It works but needs more error handling and things like wait spinners. Feel free to use it however you'd like. All of my PhoneGap related post are being cleaned and polish for a PhoneGap book I am working. I plan to self publish it on Kindle in April. And finally if you like this article please +1 it. 




References

https://dev.twitter.com/docs/twitter-libraries
http://documentcloud.github.io/backbone/
http://documentcloud.github.io/underscore/
http://www.chocolatechip-ui.com/
http://momentjs.com/
https://gitorious.org/javascript-base64


Monday, February 3, 2014

Calling Twitter API v1.1 from PhoneGap (preview)


See the finished post is here.


I am currently working my next post which is calling the Twitter API v1.1 from PhoneGap/Cordova. I just got the code executing, but I still need to do some clean up. This post is only a preview. 

In addition to PhoneGap, I also use the following open source packages: jQuery, Backbone/Underscore, ChocolateChip-UI, and Moment.JS. The end results looks pretty good and performs pretty snappy. 

jQuery does all of the ajax calls. Unlike when used in web site code, PhoneGap apps don't have any cross domain problems. Just remember to add any web site you'd wish to call to your apps white list. 

Backbone is used for its ability to keep all of my collections neatly together. Underscore while a hard requirement for backbone is also used for its ability to render client-side templates, something that is important since Twitter is only going to feed you raw data.


ChocolateChip-UI is a fantastic package which gives your apps the correct look and feel for the platform they are running on. Using PhoneGap's merges directory, you can make a build with the correct CSS files for the desired device. Besides the shown iOS and Android, it also supports Windows Phone 8. I plan to play with that just as soon as I can get my hands on a device. 


Finally there is Moment.js. It is the quintessential time handling library. Ever try to write a method to display time the way Facebook or Twitter does? You know, how long ago something was instead of when something happened? Moment has that and lots more built in. Getting the time to display correctly is a single method call.

It will probably be the weekend until I have enough time to finish the post. Besides cleaning the code up, I also want to create a plugin for it.

I am putting all of my PhoneGap code together into a book on PhoneGap. This book covers version 3+ of PhoneGap and all of things one needs to do to create production quality apps with it. Most of the code in the book has never been published. Beside using Twitter API v1.1, I cover: Audio, Video, Camera, Maps, Location, Icons, Splash pages, Debugging and setting up your build environment. I plan to self-publish on Amazon, April 2014.

Also, if you'd like more PhoneGap posts, please click the +1. I try to write post based on what I think readers like. The +1 eliminates the doubt. Thanks.

Saturday, February 1, 2014

Android Twitter Search API 1.1 App

This is the second article in this series. The first post, Android Twitter API 1.1 App, should be read first. As stated in the first article, you will need your own consumer key and secret. These are available from dev.twitter.com for free. The app described in the article will not work without the key and secret, so please don't write me saying that the app doesn't work if you didn't add your own key and secret. 

DON'T FORGET, YOU WILL NEED YOUR OWN CONSUMER KEY AND SECRET!

Understanding the Twitter Search API

Before we can begin using the API, we need to understand it. Developers often get confused by the results of their searches and assume that there is a bug in their implementation. The Search API is geared for relevance, not completeness. So searching it isn't like searching a text document, you won't get complete and exhaustive list of every tweet where your search term is found. 

Instead what you get is based on relevance. Twitter is a very fluid thing. As others send, favor, and re-tweet tweets, the relevance of tweets change. The assumption of the Search API is that you are more interested in more relevant tweets. If this is not the case, there is the Streaming API, which is based on completeness.

Using the Twitter Search API

The focus of this article is the Twitter Search API, so there isn't much of a UI here. It is the same stripped down interface that there was in the last Twitter post. But this post should make a great start for your own Twitter app whose UI you can make as elaborate as you'd like. The search term is held in the variable, SearchTerm. It can be anything that is acceptable to Twitter. The search term will be URL encoded before it is sent so don't trip over spaces and other characters. 

I moved the consumer key and secret out of the code and into the manifest file which seems more appropriate. To handle it I added a method, getStringFromManifest. Both are read in during the onCreate method and kept 

Most of the heavy lifting of the app is actually done by Google's Gson library. It converts the JSON data return by Twitter into Java objects. It is remarkably easy to use. The hardest thing here is just getting all of the types correct. Some of that information comes from the API documentation but for me it is easier to actually make the call then copy the returned data to one of my favorite websites, JSON Editor Online. From there I create all of the classes and types need to convert the JSON search data into usable objects.

Summary

While the code does work, you still got a lot of work to do if you are hoping to create a HootSuite clone. I would probably start by making the search term part of the UI and cleaning up the tweet UI.  Again please remember to enter your own consumer key and secret into the manifest.

Source Code


References: