Wednesday, February 24, 2010

iPhone SDK: Shake, Rattle & Roll - Accelerometer and Vibrate

I’d like to share with you a bit of functionality that we use in most of our applications and that I am asked about frequently: how to implement the accelerometer and the vibrate functions of the iPhone SDK.

There are three parts to the accelerometer equation:
UIAccelerometer Class: lets you register to receive acceleration related data from the hardware, this class is not directly created but rather accessed using a shared UIAccelerometer object.

UIAcceleration Class: this contains x, y, and z axis acceleration data (measured in G-force) as well as a relative timestamp.

UIAccelerometerDelegate Protocol: receives the acceleration related data from the system.

...and only one part to the vibrate equation... which we'll cover below.

For more information on the classes and protocols visit the iPhone Dev Center.

Skake: Using the Accelerometer
Implementing the use of the accelerometer is quite simple and only requires a few steps to start sensing the motion of your iPhone/iPod touch.  In this example we’re going to use a fictitious class MainViewController.

First thing we do is add the UIAccelerometerDelegate protocol to MainViewController.h allowing the class to respond to acceleration related data sent from the device.  Also, note that UIAccelerometer is part of the UIKit Framework.

#import <UIKit/UIKit.h>

@interface MainViewController : UIViewController <UIAccelerometerDelegate> {

}

@end

The UIAccelerometerDelegate protocol only has only has one instance method which delivers acceleration data to the delegate (which we’ll add to the implementation file):

- (void)accelerometer:(UIAccelerometer *)accelerometer
        didAccelerate:(UIAcceleration *)acceleration;

As the accelerometer is a shared object and is constantly updated I like to add on/off methods to my class so that I can control when the updates are handled.  For example you might want the acceleration to only happen when the view controller is visible.

Also, as the information sent from the UIAcceleration delegate is a stream of data updated at a defined interval I want to be able to create a threshold (minimum) before acting upon the data.  I add this in the method itself, but you could create a #define for each of the three axis.  Also, I’d like to point out that this is not complete code as you will still need to implement your view, init, etc, and this covers adding functionality.

Let’s add the methods and definition to our implementation file (MainViewController.m):

#import "MainViewController.h"

@interface MainViewController ()

- (void)startAccelerometer;
- (void)stopAccelerometer;

@end


@implementation MainViewController

- (void)accelerometer:(UIAccelerometer *)accelerometer
        didAccelerate:(UIAcceleration *)acceleration
{
  double const kThreshold = 2.0;
  if (   fabsf(acceleration.x) > kThreshold
      || fabsf(acceleration.y) > kThreshold
      || fabsf(acceleration.z) > kThreshold) {
    NSLog(@"Hey, stop shaking me!");
  }
}

- (void)startAccelerometer {
  UIAccelerometer *accelerometer = [UIAccelerometer sharedAccelerometer];
  accelerometer.delegate = self;
  accelerometer.updateInterval = 0.25;
}

- (void)stopAccelerometer {
  UIAccelerometer *accelerometer = [UIAccelerometer sharedAccelerometer];
  accelerometer.delegate = nil;
}

- (void)viewDidAppear:(BOOL)animated {
  [self startAccelerometer];
}

- (void)viewWillDisappear:(BOOL)animated {
  [self stopAccelerometer];
}

@end

That’s it.  Simple.  When viewDidAppear is called it calls startAccelerometer and we can start listening for acceleration related data.  If the data is above 2g then we log a message.  When viewWillDisappear is called it calls stopAccelerometer and we nil out our delegate and we stop listening for the accelerometer data.

Rattle: Vibrate
To make the device vibrate we need to use the AudioToolbox Framework.  You may be asking why audio, and that is a good question but don’t have a solid answer.  I only know how to make it work and that’s the key.

Import the AudioToolbox into the MainViewController.m file and add a declaration and method:

#import "MainViewController.h"
#import <AudioToolbox/AudioToolbox.h>

@interface MainViewController ()

- (void)vibrate;

@end

@implementation MainViewController

- (void)vibrate {
  AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
}

@end

That’s it.  And it’s simpler than dealing with the shaking of the accelerometer.  Just one line of code (more or less) and you have vibrating in your app.

Roll: Combining Accelerometer and Vibrate
What I like to do is add the vibrate method to the accelerometer:didAccelerate: method so that when user shakes their device it fires off the vibration to give haptic feedback of the action.

All you need to do is modify the accelerometer:didAccelerate: method:

- (void)accelerometer:(UIAccelerometer *)accelerometer
        didAccelerate:(UIAcceleration *)acceleration
{
  double const kThreshold = 2.0;
  if (   fabsf(acceleration.x) > kThreshold
      || fabsf(acceleration.y) > kThreshold
      || fabsf(acceleration.z) > kThreshold) {
  [self vibrate];
  }
}

Now when you shake the device, it vibrates.  Simple to implement and good user feedback.

We first implement this in our kids' application Fridgemags and I have to say that kids like shaking the device and feeling it vibrate.  We also move colored alphabet letters around  the screen and make a whooshing sound of sorts to engage the kids and keeps them busy for a good amount of time.

Tuesday, February 23, 2010

iPhone SDK 3.2 Beta 3 now available

After a day of being posted and pulled from the Apple (iPhone) Developer Center the iPhone 3.2 beta 3 is again available for download.

I just started the download process and it seems to be coming along nicely.  In a little over an hour I should have completed the download and well into the installation process.  Cheers!

Apple iPhone developers download it here.

Friday, February 19, 2010

iPhone Friday - February 19, 2010

Hello and welcome to another iPhone Friday...  We are in the process of revamping some of our older post so that we'll have some fresh new content for the iPad when it debuts.  But for now, here is a collection of iPhone and iPod touch wallpapers that are a variant of a collection I call, See Mike Play With Spot.  Enjoy!






Wednesday, February 17, 2010

iTunes Connect Developer Guide - Updated

On February 16, 2010 at 11:00AM Apple update their iTunes Connect Developer Guide (version 5.3).  After reviewing the guide I have to say Apple is making the iTunes Connect experience a little more understandable.

The guide covers and explains some of the trickier aspects of iTunes Connect such as creating a Demo Account, In-App Purchases, the New Territories feature, additional information on export compliance and overall app submission best practices.

One thing I noticed is that Apple has done away with the Device Requirements metadata (UIRequiredDeviceCapabilities) as an option - it is now a requirement.  The UIRequiredDeviceCapabilities let's iTunes and the App Store know which app related features the app requires in order to run such as video-camera, wifi, accelerometer and opengles-1 to name a few.

To download the latest version of the iTunes Connect Developer Guide login to iTunes Connect  and click the download link (at the bottom of the home page).

For more information UIRequiredDeviceCapabilities read the iPhone Application Programming Guide (specifically the section on Device Support) available in your iPhone SDK Developer Documentation or online in the Apple Developer Connection documents (Library) area.

Friday, February 12, 2010

iPhone Friday - February 12, 2010

Hello and happy iPhone Friday.  Todays collection of iPhone/iPod touch wallpapers are a set of stills from a couple of motion graphic projects.  Enjoy.





Tuesday, February 9, 2010

iPhone SDK 3.2 Beta 2 now available

Apple released the second beta of the iPhone SDK 3.2 today. I have it downloading now, but it seems to be going a little slower than normal. I guess this means it's time to get up and go for a walk... I can't wait to get back and see what new (iPhone/iPad) things are in store for us developers!

Log in and get it now!

Friday, February 5, 2010

It's the battery life, stupid!

Well, the in the news today is a series of articles in places like Information Week, Macworld, TechCrunch and even The Atlantic speculating about sinister motives on Apple's part in their recent announcement that prohibits the use of Core Location for the sole purpose of serving up advertising based on the user's current location.

Linking the announcement to Apple's recent purchase of Quattro Wireless, a mobile ad company, the speculation is that Apple seeks to reserve geo-targeted ads for itself and lock out other mobile advertisers from the iPhone platform.

While such conspiracy theories make for great water cooler conversation, I think there's a much simpler explanation: conserving battery life.

If you've ever used the Maps application for an extended period of time (hopefully not while driving :-), you've probably noticed that it drains your battery pretty quickly.  Running Core Location continuously takes a significant amount of power.  I'm not knowledgeable enough to say whether that's due to power used in cell tower triangulation or by the GPS receiver or just the amount of CPU cycles needed to turn the raw location data into latitude and longitude, but I do know that Apple recommends minimizing the using Core Location in your app and deactivating it when you have the location data that you need.  This was stressed to developers at the iPhone Tech Talks in 2008.

So whether or not Apple announces its own Core Ads API along with iPhone OS 4.0, I think don't think there's a sinister monopolistic motive behind the new rule.  I don't want every app I use to go draining my battery down just so it can serve up location-based ads that I'm going to ignore anyway.  Do you?

iPhone Friday - February 5, 2010

[Update]  After reviewing the article again and looking back I see that the original posting was from Dharmesh Shah's blog post Startup Advice In Exactly Three Words (which I also commented on and added my .02¢).


Hello and happy Friday! Last week's iPhone and iPod touch wallpaper was a lonely but playful image which I hope you enjoyed.

Earlier this week I was thinking about what I wanted to do to redeem myself and while working on artwork for an upcoming app I was reminded of Guy Kawasaki's blog post Three word wisdom from back in January.  I liked the creative mantras in the flurry of comments that ensued.  I even submitted a few of my own.

So in homage to Guy's [Dharmesh's] post and using the scene designed for the app, I offer up renderings of a few words of wisdom.  Cheers!