Posts Tagged iPhone
Use tap events instead of click events in iPhone browser
Posted by Jon in iPhone, Javascript on June 18, 2010
When working on a web app for embedding in a iPhone application we came across jQTouch, a really nifty little jQuery plugin which makes it easy to create a web application UI that really resembles that of a native iPhone application.
We soon encountered a problem due to the fact that click events are rather slow to fire on the iPhone. There is a delay due to the fact that the iPhone waits for the user to complete a gesture before deciding that the intended gesture was in fact a click.
JQTouch uses divs to navigate between screens, so for example if you have the div
<div id="primary-view"></div>
you can simply navigate to it through a normal anchor link, and the transition will thanks to jQTouch be really “iPhone like”.
<a href="#primary-view">Primary view</a>
Our main problem is that we load our content dynamically through Ajax. So our links looked like this:
<a onclick="fetchContent();" href="#primary-view">Primary view</a>
This resulted in a race condition. The anchor link listens to the tap event which is fired much earlier than the click event, and therefore we mostly ended up in empty views. So we needed to replace all onclicks to ontap listeners. The problem then is that we could no longer test our webapp in a normal desktop based Safari browser.
So, we decided to happily go along and write inline onclick events on our links and other interaction elements. But while in the iPhone we see to it that the onClicks are removed and replaced with tap listeners.
That function looks like this:
function rebindClicks(){ var userAgent = navigator.userAgent.toLowerCase(); var isIphone = (userAgent.indexOf('iphone') != -1) ? true : false; if (isIphone) { // For each event with an inline onclick $('[onclick]').each(function() { var onclick = $(this).attr('onclick'); $(this).removeAttr('onclick'); // Remove the onclick attribute $(this).bind("click", preventClickEvent); // See to it that clicks never happen $(this).bind('tap', onclick); // Point taps to the onclick }); } } function preventClickEvent(event) { event.preventDefault(); }
We now call this little function everytime the DOM is changed. If something turns up with an inline onclick. It is will be rerouted by jQuery to a tap listener instead.
Again, we felt we needed to do this because many of our developers do not have a Mac (and hence do not have the iPhone simulator). And testing on the iPhone can be really time consuming. So for testing during development we wanted to use onClick, and when testing on iPhone we wanted to use taps instead.
But the biggest bonus was without a doubt that things are overall much faster in the web application. Taps fire much faster than clicks in the iPhone.
Here’s how it looks running the same app both in desktop safari and embedded into the iPhone simulator.
Submitting iPhone app to App Store
Posted by Samuel in Innovation, iPhone on May 8, 2009
Finally, after two bounces and three weeks of waiting, our first app on App Store is available!
I’ll keep this post really short!
Pros
Cons
Some good to knows!
The App Store review process: 4 stars out of 5Conclusion
If you are curious about our iPhone application, please visit our app section @ App Store.Projectplace for iPhone
Use Flex and set it free
Posted by PEZ in Flex/AS, Innovation, iPhone, Values on April 17, 2009
I work at Projectplace Labs. In fact I’m managing it. No doubt it’s the best job I’ve ever had. Imagine getting payed for experimenting with far out things all day. Two examples:
- Samuel, who also works at the lab and blogs on this site, started to play with the iPhone SDK some month ago and just yesterday he sent a Projectplace client for the iPhone to AppStore. It should appear there any day soon. Computer Sweden wrote about it today (Swedish).
- A year ago I tried out Sandy3D (awesome 3D engine for Flash written in AS3) and quickly got a prototype up for a Cooliris-inspired photo wall, it was WOW to me so I called it WowAlbum. Not as immediately business applicable as Samuel’s iPhone app, but a fun thing to do.
Projectplace Labs is very much inspired by those big, innovative, forces out there. Mozilla Labs, Microsoft Office Labs, Adobe Labs and, of course, Google Labs. Google is probably our main inspirational source. We’re trying to reverse engineer Google’s innovation machine and apply what we feel fits us (or at least try to convince our managers to let us apply it). We’ve also taken Quincy Jones’ receipt for success to our hearts;
We apply it on all levels. Ideas, creativity, people, innovation, inspiration, code, joy, love. Unleash!

Yap - planning made fun
Ummm, I was definately not planning to write about Projectplace Labs in this blog. Got a bit carried away there. I was mainly about to use the Bagonca server to make a development version of Yap available to a guy I’m working with at A-Dato. Then I thought, heck I can blog about it, and then I felt I needed to tell about where I work.
And now I need to tell you something about Yap too, right? You can read a little about it at Projectplace Labs and also at Projectplace Ideas. To cut a long story short:
We, Projectplace, want to be the company who made project planning fun.
That development version of Yap that you can access even before it appears on Projectplace Labs? Don’t worry, I haven’t fogotten, here goes:
Now, how cool does this make Bagonca? It even publishes Projectplace Labs stuff before Labs! =)
iPhone tip #2 – What is my current location?
The iPhone has GPS built-in, which makes the phone really powerful and enables developers to innovate cool and cutting edge applications!
The iPhone devcenter has some sample code explaining how the CoreLocation framework works. But, I found that example a bit hard to understand…
Here is an easier way of finding your current location from your iPhone.
Let’s start with the interface/header file.
CurrentLocationController.h
#import <CoreLocation/CoreLocation.h> @interface CurrentLocationController : NSObject <CLLocationManagerDelegate> { CLLocationManager *locationManager; } @property (nonatomic, retain) CLLocationManager *locationManager; - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation; - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error; @end
Note: Our object “implements” the CLLocationManagerDelegate protocol. We “implement” two methods, locationManager:didUpdateToLocation:fromLocation: and locationManager:didFailWithErrorfrom :, from CLLocationManagerDelegate. The first method is invoked when a new location is available and the second one if an error has occurred.
Here comes the implementation:
#import "CurrentLocationController.h" @implementation CurrentLocationController @synthesize locationManager; - (id) init { self = [super init]; if (self != nil) { self.locationManager = [[[CLLocationManager alloc] init] autorelease]; self.locationManager.delegate = self; } return self; } - (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation { NSLog([newLocation description]); } - (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error { NSLog([error description]); } - (void)dealloc { [self.locationManager release]; [super dealloc]; } @end
The only important thing to note is the line
self.locationManager.delegate = self;. Here we set our own object as the delegate, which means that all the location messages will be forwarded to CurrentLocationController.
I hope this will give you more time innovating, instead of developing Trichotillomania.
iPhone tip #1 – URL encoding in Objective-C
If you are n00b when it comes to iPhone development, then you’ve come to the right place! We’ll be posting howtos, tips and tricks continuously.
So, how do you URL enconde a string? It’s quite simple if you know how. :)
+ (NSString *)urlEncodeValue:(NSString *)str { NSString *result = (NSString *) CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)str, NULL, CFSTR(”:/?#[]@!$&’()*+,;=”), kCFStringEncodingUTF8); return [result autorelease]; }
To create an URL object, do like this:
[NSURL URLWithString:encodedUrlString]
