Skip to Navigation | Skip to Content



Phonegap contributor agreement | February 1st, 2010

Over the weekend, I submitted the Nitobi Contributor Agreement to the PhoneGap mailing list and created a minor sh!t-storm.  I did a few things wrong and as a result it became obvious that our intent was left unclear. This post is my attempt at reaching clarity.
Many of the things we at Nitobi were accused of attempting with this agreement are precisely the things we are attempting to prevent.
The document was mis-titled and very misleading, it reads “Nitobi Creative Commons Contributor Agreement”, when it should have been titled, “PhoneGap Contributor Agreement”.  The actual document itself is licensed Creative Commons Attribution-Share Alike 3.0 Unported, not PhoneGap!
I was not clear enough in informing everyone that the license for PhoneGap is NOT changing,  and it will continue to be MIT licensed.  The agreement is being put in place to protect that.
Contributors are NOT giving up their rights, or blindly assigning their rights to Nitobi, they are agreeing to SHARE their rights with Nitobi.  Contributors give up nothing and are free to do what they want with their own submissions, short of revoking the rights they have granted to Nitobi. There is NO danger that contributions can be made exclusively proprietary.
The agreement implies that mailing list conversations are covered, or this is how some readers interpreted it.  This is absolutely NOT true: the mailing list, wiki and likewise PhoneGap documentation are not covered by this (or any) agreement, and we will be updating the agreement to make this obvious.
So to repeat, as clearly as possible: PhoneGap is and will remain under the MIT license and be freely available for use in your applications ( for fun OR profit ).  You do not need to sign anything to use PhoneGap in your applications, you just need to agree to the MIT license.  Only those wishing to contribute back to the project ( via checkin to the repository ) will need to sign the agreement.
As always, we remain committed to Open Source and the community surrounding it, and will work with the community to do the right thing.
If you wish to comment on the agreement, or PhoneGap please feel free to do so in the group mailing list. http://groups.google.com/group/phonegap/

Over the weekend, I submitted the Nitobi Contributor Agreement to the PhoneGap mailing list and created a minor sh!t-storm.  I did a few things wrong and as a result it became obvious that our intent was left unclear. This post is my attempt at reaching clarity.

Many of the things we at Nitobi were accused of attempting with this agreement are precisely the things we are attempting to prevent.

  • The document was mis-titled and very misleading, it reads “Nitobi Creative Commons Contributor Agreement”, when it should have been titled, “PhoneGap Contributor Agreement”.  The actual document itself is licensed Creative Commons Attribution-Share Alike 3.0 Unported, not PhoneGap!
  • I was not clear enough in informing everyone that the license for PhoneGap is NOT changing,  and it will continue to be MIT licensed.  The agreement is being put in place to protect that.
  • Contributors are NOT giving up their rights, or blindly assigning their rights to Nitobi, they are agreeing to SHARE their rights with Nitobi.  Contributors give up nothing and are free to do what they want with their own submissions, short of revoking the rights they have granted to Nitobi. There is NO danger that contributions can be made exclusively proprietary.
  • The agreement implies that mailing list conversations are covered, or this is how some readers interpreted it.  This is absolutely NOT true: the mailing list, wiki and likewise PhoneGap documentation are not covered by this (or any) agreement, and we will be updating the agreement to make this obvious.

So to repeat, as clearly as possible: PhoneGap is and will remain under the MIT license and be freely available for use in your applications ( for fun OR profit ).  You do not need to sign anything to use PhoneGap in your applications, you just need to agree to the MIT license.  Only those wishing to contribute back to the project ( via checkin to the repository ) will need to sign the agreement.

As always, we remain committed to Open Source and the community surrounding it, and will work with the community to do the right thing.

If you wish to comment on the agreement, or PhoneGap please feel free to do so in the group mailing list. http://groups.google.com/group/phonegap/

Posted in PhoneGap | No Comments » | Add to Delicious | Digg It

PhoneGap iPhone Tutorial – A good place to start | January 14th, 2010

PhoneGap has been getting a lot of attention lately, and also a lot of questions on the mailing list about where to get started.
I recently built a small PhoneGap app for iPhone that helps to demonstrate PhoneGap functions.

The application is divided into multiple pages, and each page focuses on one area of functionality.
I have strived to keep each page dedicated to the functionality it presents, and present everything as simply as possible.
There are no dependencies on any other libraries, and the js / css for each page is contained directly there.

The Notifications page demonstrates key navigator.notifications functions.

  • Custom Alerts – with custom title text, and button text.
  • Display a loading screen for a fixed length of time
  • Vibrate the device
  • Show and hide the Activity Indicator ( the spinner at the top bar )

The Accelerometer page demonstrates navigator.accelerometer functions.

  • Start + Stop the accelerometer update logic, and play with a bouncing ball.

( a shout out to Yohei for providing the initial code for this example. )

The Contacts page demonstrates navigator.contacts functions.

  • Display the number of contacts
  • Spawn the contact picker screen
  • Renders a contact, and makes it clickable, to spawn the contact viewer.

The GeoLocation page demonstrates how to use navigator.geolocation

  • Gets your current location
  • Calls Twitter api using JSONP to get tweets within a mile of your location

( a shout out to Girlie Mac http://girliemac.com/blog/ this code was shamelessly borrowed )

Hopefully the other platformers will step up and publish / test on other devices.  I have only worked on the iPhone branch so far.

I will be working on the Media api next to demonstrate how easy it is to play mp3s within PhoneGap, and I might even post some of my own music, we’ll see.

Get it while it’s hot! http://github.com/phonegap/phonegap-iphone

Posted in Uncategorized | No Comments » | Add to Delicious | Digg It

PhoneGApp Store Approval | November 20th, 2009

I just received word from Apple that :

a) Apple has given PhoneGap a technical analysis , and PhoneGap does not violate the Terms & Conditions of the App Store.
b) Apple will review PhoneGap applications based on their own merits and not on their use of PhoneGap.

What this means:

There was still some apprehension within the community as to whether or not using PhoneGap would lead to a possible rejection from the iPhone App Store, we definitely have a green light to PhoneGap. This means we can all get back to doing what we love best, building fast, easy mobile apps with JavaScript+HTML+CSS while still taking advantage of the core features in the iPhone, Android, Symbian-WRT and Blackberry devices.

Happy coding!

Posted in PhoneGap, iPhone | 13 Comments » | Add to Delicious | Digg It

PhoneGap for iPhone exposed | November 4th, 2009

Earlier this week I attended the Apple iPhone Developers Tech Talks in Seattle. The event was free and by invite only and you had to have an app in the app store, or be very close to having one to be invited. This meant that the content of the talk could be technical without losing anyone, and we had an informative deep dive into technical things like OpenGLES, Device Audio, and UIKit functionality best practices. I learned a lot over the day about what to avoid, and how to optimize iPhone applications.

As a PhoneGap developer, user and evangelist, I made it my duty to talk to everyone I could about PhoneGap and guage the level of interest from the Apple dev community. After speaking to a couple people at Apple, it became clear that they are very much aware of PhoneGap, but have very little understanding of what it does or how it works. I have decided to dig into these questions to make sure that there are no misconceptions about the project.  PhoneGap is entirely opensource, but not everyone has the time read a bunch of code. ( if only …)

PhoneGap Under the Hood

PhoneGap aims to provide a consistent interface to device functionality across multiple platforms to enable rapid application development via well known technologies, namely HTML / JavaScript / CSS.

At it’s core, PhoneGap is nothing more than a spec listing JavaScript accessible calls that an application programmer can use to make applications. Each device ( iPhone, Android, BlackBerry, … ) has it’s own specific implementation, and the tools and processes you use to build, test and deploy/submit your app will vary for each. So again, PhoneGap is a JavaScript accessible API implemented on multiple devices.

All implementations render their user interface using HTML and CSS in a web browser control of some sort. Most modern devices support rich rendering features ( HTML5, CSS3 ) so it is a relatively simple to design, and layout your application with your existing skills, tools, and even existing graphical assets.

The typical PhoneGap application is a packaged version of a webpage/website that runs from the phone. What this means is that all html/css/js files are bundled into the application and run from the file:// protocol. A common misunderstanding is that the application is loaded over the web, which is definitely NOT the way we recommend users write their apps, and (to my knowledge) NOT the way typical PhoneGap based applications are architected. In this case you would be writing a mobile-optimized website and will likely not be approved for app store submission.

In some cases PhoneGap applications have a server component that delivers data via an HTTP API, usually json or xml using XMLHttpRequest. PhoneGap itself does not provide any server communication functionality, so app developers must roll their own server access layer.

So How Does PhoneGap Work?

Every device implementation has it’s own specific means of accessing device functionality, so I will be focusing on the iPhone implementation. The iPhone implementation is probably the most misunderstood, and most used, plus it is where I have spent the most time.

How does JavaScript call Objective-C code?

In order for a developer’s application code (js) to access device functionality they will include the file phonegap.js in their (html) application. The file phonegap.js defines the entire API and contains the key functionality for device communication. All device functionality that PhoneGap exposes is done via the navigator object in JavaScript.
For example, to access Accelerometer functionality, you would call JavaScript methods on the navigator.accelerometer object.

In order for phonegap.js to send a request to the device it simply sets the location of the page based on the following protocol:

gap://CommandHandler.method?arg1Name=arg1Value&arg2Name=arg2Value

gap://
This is a phonegap request and not a request to load a new page.
CommandHandler
This is a subset of device functionality that contains methods. An example would be Accelerometer or Notification
method
Each CommandHandler defines it’s own methods
arguments
a URL encoded list of arguments that are passed to the method ( varies based on the method ) Note that phonegap.js will URLEncode the parameters for you.

and here’s a concrete example:

gap://Notification.alert?message=Hello&title=My%20App%Name&buttonLabel=OK

This will call the Notification objects alert method, passing it a message,title, and the text to display on the button.

So, upon receiving the command, Objective-C code will take over and perfom the requested command.

So How Does Objective-C call my JS code?

Some calls from JS require a callback mechanism to let the JS code know when the command has completed, if it succeeded and so on. The majority of this is handled for the developer in phonegap.js. Objective-C code will call stringByEvaluatingJavascriptFromString() to pass data back into the js code. The mechanism for each command is defined in phonegap.js, so the developer will simply pass a function callback that phonegap.js will call once the command has returned data.

Here is a concrete example:

In my application, I want to access the accelerometer, so I define a callback function :


function onAccelData(accelObj)
{
// accelObj has properties x,y,z that you can use to see the
// current state of the accelerometer so presumably you
// would do something with that data here.
}
function onAccelFail()
{
// accelermeter functionality is not available,
// do something else ...
}

In order recieve the data, I need to make a call to the js Accelerometer object :

navigator.accelerometer.watchAcceleration(onAccelData, onAccelFail);

Now, your callback is going to be called repeatedly with updated accelerometer data, that your application can use as you see fit. Since this is not intended to be a blog post about how to use the accelerometer, I will stop there. You should know also that the accelerometer supports stopping as well, and you can also specify how often you want to be updated.

So that, in a nutshell, is the entire iPhone implementation of PhoneGap. Note, there is no voodoo or magic sauce, just 2 data transfer mechanisms and a protocol between them.
Hopefully this will give better perspective and help anyone who has to answer the question: What is PhoneGap?

Remember that PhoneGap is completely opensource so if you want a deeper look under the hood, you are completely free to do so.

If you want to use PhoneGap, you can git it here :http://github.com/phonegap/phonegap
To read more, have a look at www.phonegap.com

I invite your questions, comments, criticism, accolades, beers!

Posted in Objective-C, PhoneGap, iPhone | 4 Comments » | Add to Delicious | Digg It

Running jQTouch in PhoneGap | October 28th, 2009

Last week there were some discussions about the poor performance of jQTouch in PhoneGap apps, so I dug into it.

First I had to verify that this was something we were doing in PhoneGap and not a difference between Mobile-Safari and the UIWebView control which we use in PhoneGap.

I created a PhoneGap project and dropped the jQTouch sample code into the www folder, and immediately noticed the sluggish performance.

I then created a bare bones iPhone Windowed application with a UIWebView in it, and dropped the same www folder contents into the project root.

NSURL *appURL = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"index" ofType:@"html" inDirectory:@"www"]];
NSURLRequest *appReq = [NSURLRequest requestWithURL:appURL cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:20.0];
[webView loadRequest:appReq];

After running both builds on the device it was obvious that the PhoneGap version was in fact sluggish compared to the bare-bones version. Verified!

So, thinking about what could be causing this, I looked into the PhoneGapDelegate code, and immediately saw the Accelerometer handling code the a potential culprit. The PhoneGapDelegate class asks the sharedAccelerometer for updates 40x per second. According to the Applei Phone dev docs, this interval is “Suitable for games and other applications that use the accelerometers for real-time user input.” Which is cool, but probably way more than this application needs considering it isn’t even being used. Every time that the sharedAccelerometer calls back with an update, the javascript is written into the webView’s DOM. Commenting out the accelerometer code that sets up the interval indeed fixes the majority of the sluggishness. Verified! Pretty smooth, eh?

Okay, so commenting it out isn’t really a solution, so here is the plan:
I am working to re-implement the Accelerometer portion as a command, that can be used more elegantly. Javascript code inside the www folder should have the ability to set how frequently it wants be updated, and have the ability to start + stop monitoring the accelerometer, which should also remove the overhead.

Note:
If your application does not use the accelerometer, instead of commenting out the code like I did, you can simply set “EnableAcceleration” to false in PhoneGap.plist.

I will post an update here when I have checked in anything of significance.

Posted in Objective-C, PhoneGap, Uncategorized, XCode, iPhone | 10 Comments » | Add to Delicious | Digg It

PhoneGap Static lib for iPhone-XCode | October 27th, 2009

I recently spent some time evaluating the iPhone branch of PhoneGap and have made some changes that I think will make things easier to develop.

One of the key issues that I wanted to address was that PhoneGap existed as a repository and anyone that made an application with it would invariably have to mix their code in. In a very few cases it is possible to make a complete application using PhoneGap out of the box, but what if you need to add, remove or change something? As soon as you start messing with the core PhoneGap code, you are looking at huge merge issues when updates are pushed to the PhoneGap repo. Most likely you will just ignore any new commits, and your code will be stuck in time from the moment you changed it, or you will have to pick through the updates, and decide what is worth re-implementing in your own codebase.

My changes work as follows: You do not create a PhoneGap app anymore! You create an app that inherits from PhoneGap. This means your PhoneGap code can be in a git repo somewhere (github) while your application code can be in it’s own repo. If there are updates to the PhoneGap codebase then ( as long as the API has not changed ) you simply update PhoneGap and build your app.

In order to make these changes, I had to simplify some of the PhoneGap code. I removed the dependency on XIB files so the UIWebView is now created through code instead of automagically by XCode boilerplate code behind the scenes. The PhoneGap core code is now a static library that you link to and inherit from so there are some things you will have to do to create a new phonegap application. Also keep in mind that this is all subject to change as we are currently looking at ways of making this dead-simple.

You can git the code here: http://github.com/phonegap/phonegap/tree/plugins/iphone/

The new PhoneGap 12 step program

  1. In XCode create a new WindowBased iPhone Application.
  2. Select the project and add a reference to the PhoneGapLib project. ( The one you downloaded from git )
  3. Add a reference to all headers in the PhoneGapLib project ( these are needed so the compiler can know what you will be linking against, and what the base PhoneGapDelegate protocol looks like )
  4. Delete the MainWindow.XIB interface builder file that XCode created.
  5. In main.h add your app delegate class name to the UIApplicationMain call.
    ex.
    int retVal = UIApplicationMain(argc, argv, nil,@"MyAppDelegate");
  6. Change the interface of your application delegate to inherit from PhoneGapDelegate.
    ex.
    @interface MyAppDelegate : PhoneGapDelegate { }
  7. Select the build target in your project and add a dependency for PhoneGapLib.
  8. Add libPhoneGapLib.a to the ‘Link Binary with Library’ build step.
  9. Add the www folder to the ‘Copy Bundle Resources’ build step.
  10. Place phonegap.js in your www folder along with all your html/css/js application code.
    ( note: this is a little bit hack-y, and we are looking at ways of improving this step especially )
  11. Add project references to the following frameworks
    • AddressBook.framework
    • AddressBookUI.framework
    • AudioToolbox.framework
    • AVFoundation.framework
    • CFNetwork.framework
    • CoreGraphics.framework
    • CoreLocation.framework
    • Foundation.framework
    • MediaPlayer.framework
    • QuartzCode.framework
    • SystemConfiguration.framework
    • UIKit.framework
  12. Build and Go.

So What’s Next?

Recent PhoneGap discussions have led us to the conclusion that we need a plug-in architecture. It will be much easier to get people to contribute if they can focus on a key piece of functionality and not have to implement things throughout the codebase + it also gives a clearer separation of contributions and would allow for unit testing.  This latest addition/change is a step towards a more plug-able architecture. Thanks also to Shazron for his help, support and suggestions along the way.

So get reviewin’ !!

Posted in Objective-C, PhoneGap, XCode, iPhone | 8 Comments » | Add to Delicious | Digg It

Image Caching with the HTML5 Canvas | September 24th, 2009

Lately I have been working on an iPhone app ( using PhoneGap of course )  and needed to implement image caching on the client with javascript.

I am already using an SQLite database in mobile safari, so I decided I could store images in Base64 in the DB.  I was able to load the binary image data using XHR, but could not correctly encode it to base64 in javascript.

Exploring another path, I found that there is a method of the HTML5 Canvas toDataURL();

So I wrote this to download the image, instead of my XHR method :



ImageCacheManager.prototype.fetchImage = function(url)
{
var alias = this;
var img = new Image();
img.onload = function()
{
alias.onImageLoaded(this);
};
img.src = url;
}

Then this to handle the loaded image and cache it :



ImageCacheManager.prototype.onImageLoaded = function(img)
{
var canvas = document.createElement("canvas");
canvas.width = img.width;
canvas.height = img.height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img,0,0);
var dataURL = canvas.toDataURL();
this.cacheImageData(img.src, dataURL);
}



To keep things short I have excluded the DB sections, I always check if I have an image cached already before I fetch one, and always write it to the DB when I do fetch.  If an image is retrieved from the DB it can simply be written to the img.src as is.


I foresee all kinds of uses for this, like a javascript based image editor, or a water-marking script ( you can also draw text on the canvas before you pull out it’s bits … )

Posted in Uncategorized | 3 Comments » | Add to Delicious | Digg It

YuTuplr – Getting Started. | May 28th, 2009

Lately in my spare time I have been quietly plugging away at building a simple YouTube uploader application in Air.  Nitobi encourages us to spend part of our time on our own pet projects, as well as community interaction and contributing to open source initiatives.  I have been working on this application ( YuTuplr – as in a short form of YouTube Uploader ) primarily by myself, so it has forced me to reach outside my comfort zone, and do some things that I usually take for granted.  I have approached this project as if it were a stand-alone product, so it has it’s own logo, branding, domain, and website.   All of my work, with the exception of some developer keys and fonts is open source and is available on google code.

I am posting the following as sort of a quick start guide for anyone who wants to add YouTube upload functionality to their own Air apps, or just learn some AS3.  For the complete picture, please download and study the YuTuplr source.

The application is seperated into 2 seperate flex projects.

The AirYouTubeUploaderLib is a Flex/Air library project that contains all of the functionality related to YouTube.  The goal was to hide the low level stuff, and allow API users to build client application without the greasy YouTube API details.

YuTuplr is a somewhat full-blown example of a client, and can be used as a guide for building your own clients.  YuTuplr’s source code is in the project AirYouTubeUploaderSampleApp and contains a reference to the AirYouTubeUploaderLib project.

The YouTubeService class is the main point of interaction with your code.

To get started using the service, simply create an instance, and give it your YouTube developer credentials. You will need to get your credentials from YouTube.


import com.nitobi.webapis.youtube.YouTubeService;
ytService = new YouTubeService();
ytService.setCredentials(clientID,devKey);

Authentication

You can look at ytService.isAuthenticated to see if you are already logged in, and currentUserName to get the current user’s name.

To login, simply call :
ytService.login(userName:String,password:String,rememberMe:Boolean = true):void

If the rememberMe flag is true, the YouTubeService will store the username/password in a LocalSharedObject.

To retrieve the previously stored values, YouTubeService has public getters : 
storedUsername():String 
storedPassword():String

Both getters will return “” if the last login did not set rememberMe to true.

YuTuplr uses this information when it initializes the login window like the following:

usernameInput.text = ytService.storedUsername;
passwordInput.text = ytService.storedPassword;
cbRememberMe.selected = usernameInput.text.length > 0;

The service will dispatch the following YouTubeEvent(s) related to login:

YouTubeEvent.YT_LOGIN_START - the service is attempting to log in, use this to display a spinner or disable a log in button

YouTubeEvent.YT_LOGIN_SUCCESS - all systems go! The user has been authenticated.

YouTubeEvent.YT_LOGIN_ERROR - there was an error logging in, bad username or password.

Getting the user’s Uploads

The service exposes several bindable ArrayCollections for data storage.

YouTubeService.userUploads - a collection of UserUpload objects, all in various states.  Some may be completed, but still in the list, others may be pending or failed.

Upload status is statically defined by the UserUpload class

UserUpload.STATUS_UPLOADING - the file is currently being uploaded

UserUpload.STATUS_COMPLETED - the upload has completed

UserUpload.STATUS_ERROR - the upload failed

UserUpload.STATUS_QUEUED - file is in queue, and will be uploaded according to it’s order in the queue

UserUpload.STATUS_PENDING - this upload is being edited (meta) and should not be uploaded yet

- set the status to STATUS_PENDING to prevent the uploader from trying to upload a file while the user is editing the details.

In order to add to YouTubeService.userUploads, simply call YouTubeService’s addFile method passing it a file object.  If the file object is a directory, the service will locate all supported video files (by extension) within it and add them to the list.

public function addFile(file:File):Boolean;
public function addFiles(fileList:Array):Boolean;

The service also provides methods for cleaning up the list:

To remove all uploads that have a status of complete:

public function clearCompletedUploads():void

To retry all failed uploads: 
public function retryFailedUploads():void

- Behind the scenes, this resets status to UserUpload.STATUS_QUEUED and they will be uploaded according to their order in the queue.

To remove failed uploads:
public function removeFailedUploads():void

To remove an individual UserUpload from the queue:
public function removeFileFromQueue(upld:UserUpload):void

 
A key goal in the design of the architecture was to support binding throughout.

You can safely bind a list control to the UserVideos collection, and when updates are received from YouTube the same object instances are updated with the new values.  This makes the service pretty easy to interact with, as binding does most of the work.

YouTubeService.userVideos

The userVideos ArrayCollection is a list of all the users previously uploaded videos. Each item in the list is of type :UserVideo

UserVideo have the following properties:

id:String; // the unique id assigned by YouTube
thumbnail1:String;// URLs to video images.
// Note: the thumbnails are null until YouTube has processed the movie
thumbnail2:String;
thumbnail3:String;
durationSeconds:int;
viewCount:int;
commentsCount:int;
published:Date;
updated:Date;
status:String; // UserVideo. ( STATUS_PROCESSING | STATUS_ACTIVE | STATUS_REJECTED )
reason:String; // ie. Duplicate video ( this is only available if status == STATUS_REJECTED )
description:String;
keywords:String;
rating:Number = 0;

The UserVideo also has a getter for formatted duration, which returns a formatted time string MM:SS
get formattedDuration():String

YouTube events dispatched by the service

Your application will want to subscribe to events to know what is happening with the service.

YouTubeEvent statically defines all the events that the service will dispatch.

YouTubeEvent.YT_LOGIN_START - the service is attempting to log in, use this to display a spinner or disable a log in button

YouTubeEvent.YT_LOGIN_SUCCESS - all systems go!

YouTubeEvent.YT_LOGIN_ERROR - there was an error logging in, bad username or password

YouTubeEvent.YT_GOT_USER_VIDEOS - the authenticated user’s videos have been retrieved from YouTube

YouTubeEvent.YT_NO_CREDENTIALS - an API call was attempted, but you have not set the developerKey and clientID.

YouTubeEvent.YT_UPLOAD_SUCCESS - an upload has successfully completed

YouTubeEvent.YT_UPLOAD_ERROR - there was an error uploading a file.

YouTubeEvent.YT_UPLOAD_COMPLETE - an upload has completed, this is fired both on success and error conditions

YouTubeEvent.YT_UPLOAD_PROGRESS - YouTubeEvent.data contains bytesLoaded and bytesTotal that you can use to bind directly to a progress bar.

YouTubeEvent.YT_PROCESSING_COUNT_CHANGE - when videos are uploaded to YouTube, they must be transcoded before they are available.  The YouTubeService keeps tracks of how many UserVideos are processing and fires this event whenever the count changes.

YouTubeEvent.YT_FILESIZE_EXCEEDED - the user has added a file that is over the YouTube defined 1 GB limit

 

Hopefully that is enough to get you started playing with the YouTube Uploader Library.  I welcome all comments, questions, suggestions and especially contributions if anyone wants to jump in and help push the app to the next level.

Jesse

Posted in Adobe Air, Air, Flex | 8 Comments » | Add to Delicious | Digg It

The race to the MegaTweet | April 17th, 2009

The day started like any other day, sitting tired on SkyTrain on my way to work, when I happen to catch the headline on the newspaper of the commuter in front of me.  ”Kutcher’s race to a million twitter followers.”  With peaked intrest I pulled out my iPhone and read some more about it.  

Ashton Kutcher had some 9 hundred something thousand followers on Twitter, and was close behind CNN in the number one position.  Both were approaching 1 million so I guess it seemed to be the likely target.  After watching Ashton’s YouTube video ( BTW: I love my iPhone 3G ) I was a little perturbed by Ashton’s claim that his reaching 1 million followers would somehow signal a new age because (heavy paraphrasing here) “… an everday person has a greater reach than the media conglomerate … “.  My problem was with the claim that Ashton was somehow representive of ‘everone’, not that I have anything against him, but he has a great deal more celebrity than most will ever achieve, so he hasn’t lived in the ‘everyman’ world for quite awhile.  My immediate reaction was simple: “Fuck him, I’ll do it first! I’ll beat ‘em both, because I AM everyman!”.

When I got to work, I ran the idea past a couple co-workers, and they were supportive, so I went to Twitter and created a new account http://twitter.com/Power2TheTweepl ( Ashton had used the term ‘Power to the people” in his YouTube video ). Next I proceeded to follow everyone I was really following in my other ‘real’ account, careful not to follow myself first and give away my real identity.

I then sent an email to the team @nitobi and told them what I had started, and giving them a call to action to get the word out.  I got some great recommendations for profile images (#1, #2) from Brian, but in the end chose to go a different way.  I immediately got some follows from the team, and some retweets of my initial messages, and I was off to the races.

I spent some time following people, strangers really, hoping they would follow me back … and alot did.  I chose people to follow by going after twitter users who had large numbers of followers, jumping to their ‘followers’ page and haphazardly clicking follow ( I love Ajax! )  I didn’t spend a lot of time on this, as I also have a job to do, but did learn some stuff, which I’ll get to.

Ashton eclipsed CNN at about 7:00 PM and around 11:00 PM PST, Ashton reached a million followers. This isn’t a news report, so if you want the details of what happened, check it out here.  I was able to get 130 followers, including @NitobiMouse.

Okay, the lessons.

 

  • if you follow a stranger they will usually follow you back, at least for a little while.
  • if you follow someone who has no followers, you might scare them, and they might send you a message saying something like ‘Why are you following me?’  ( Oprah’s followers are heavy in this category )
  • twitter is still new to A LOT of people.
  • twitter is pretty amazing when you think about how vast the system is. (I only saw ~8 fail whales)
  • does this matter? Who cares!
  • I’m not as popular as Ashton Kutcher ( yet… ) 
  • Ashton is donating Mosquito nets to Africa, so some good is coming from all this.

 

While writing this I got 8 new follows, so I may still keep the account active, we’ll see.  Also, I was not the only person to have this reaction, @TotalNobody had the same idea …

My final thought.  Tomorrow, Oprah will be posting her first tweet live on her show, so Twitter is becoming less social and more of a platform everyday.  Not sure if this is a good thing, a bad thing, or if it is even a thing.

Thoughts?

Jesse

 

 

 

Posted in Uncategorized | No Comments » | Add to Delicious | Digg It

Overlay.tv – YouTube Uploader Pt.2 | February 17th, 2009

Integration with Overlay’s services was somewhat easier. They have a published API but unfortunately for this project, it is intended for use on other websites, so it did not make sense in a client application.

Overlay also has a flash movie that they use in their pages to support viewing, creating and editing overlays. The flash movie is an AS2 movie, so I was not able to load it directly, but instead ended up creating an HTML control and dynamically modifying the flashvars to get at the functionality we needed. ( BTW I love the HTML control in Air! ) The Flash movie already implemented 100% of overlay’s functionality, so I was very glad to be able to use it directly.

Working closely with Overlay, I was given instructions on how to authenticate a user and get xml back.  For getting the list of the current user’s overlays we consumed just grabbed the user’s rss feed. 

So go check out the Overlay.tv YouTube uploader and start making some overlays!.  

Your feedback is welcomed.

Cheers,

  Jesse

 

Posted in Adobe Air, Flex | No Comments » | Add to Delicious | Digg It