Android Development – Setting your location using latitude, longitude in the emulator

This is a quick post since it took me a little while to figure this one out. If you are using location services in your application and testing them on the emulator, you might be wondering how to set your location. In fact the iPhone doesn’t provide for this and defaults you to Cupertino (Apple’s HQ) which can be annoying.

But Google have thought a bit more about it. All you need to know is the port your emulator is running on (it’ll be in the title bar of the emulator), typically 5554.

Fire up a terminal and away you go, let’s say you want to set it around London, UK. That is roughly 52,0 in lat long so connect to the port through Telnet and enter:

telnet localhost 5554
geo fix 52 0 0

The final 0 is optional and sets your altitude. Easy, and now in your application your callback method onLocationChanged should be called.

iPhone Development – Gradient background UIViews

Here’s a neat little tip I’ve found can spruce up your applications easily. It’s very easy to create a UIView with a solid background colour, but in our new rainbow coloured Web 2.0 shiny iPhone world, gradients are called for. You could of course create a gradient image and set the background image of the view, but this has several drawbacks:

  • For every different sized view, you either need to re-cut the gradient image or scale it.
  • It is a waste of space in your application, plus gradient images are often quite big files.
  • You need an image for each colour.
  • It is relatively expensive to load and render an image as a background for a view.

However using a bit of trickery, you can create a general GradientView class which extends UIView and overrides drawRect to achieve a gradient background. So I present GradientView:

//
//  GradientView.m
//  evilrockhopper
//
//  Created by Daniel Wichett on 10/12/2009.
//
//  Extension of UIView to show a gradient, generally used as a background on other views.
//  Mirrored indicates a gradient that is colour1 -> colour2 -> colour1. Non-mirrored simply goes from colour1 -> colour2.

#import "GradientView.h"

@implementation GradientView

@synthesize mirrored;

- (void)drawRect:(CGRect)rect
 {
    CGContextRef currentContext = UIGraphicsGetCurrentContext();

    CGGradientRef glossGradient;
    CGColorSpaceRef rgbColorspace;
    size_t numLocations = 2;
    CGFloat locations[2] = { 0.0, 1.0 };

    //Two colour components, the start and end colour both set to opaque.
    CGFloat components[8] = { startRed, startGreen, startBlue, 1.0, endRed, endGreen, endBlue, 1.0 };

    rgbColorspace = CGColorSpaceCreateDeviceRGB();
    glossGradient = CGGradientCreateWithColorComponents(rgbColorspace, components, locations, numLocations);

    CGRect currentBounds = self.bounds;
    CGPoint topCenter = CGPointMake(CGRectGetMidX(currentBounds), 0.0f);
    CGPoint midCenter = CGPointMake(CGRectGetMidX(currentBounds), CGRectGetMaxY(currentBounds)/2.0);
    CGPoint bottomCenter = CGPointMake(CGRectGetMidX(currentBounds), CGRectGetMaxY(currentBounds));

    if (!mirrored)
    {
        // draw a gradient from top to bottom centred.
        CGContextDrawLinearGradient(currentContext, glossGradient, topCenter, bottomCenter, 0);
    }
    else
    {
        // draw a gradient from top to middle, then reverse the colours and draw from middle to bottom.
        CGContextDrawLinearGradient(currentContext, glossGradient, topCenter, midCenter, 0);
        CGFloat components2[8] = { endRed, endGreen, endBlue, 1.0, startRed, startGreen, startBlue, 1.0 };
        CGGradientRelease(glossGradient);
        glossGradient = CGGradientCreateWithColorComponents(rgbColorspace, components2, locations, num_locations);
        CGContextDrawLinearGradient(currentContext, glossGradient, midCenter, bottomCenter, 0);
    }

    // Release our CG objects.
    CGGradientRelease(glossGradient);
    CGColorSpaceRelease(rgbColorspace);
}

// Set colours as component RGB.
- (void) setColours:(float) _startRed:(float) _startGreen:(float) _startBlue:(float) _endRed:(float) _endGreen:(float)_endBlue
{
	startRed = _startRed;
	startGreen = _startGreen;
	startBlue = _startBlue;

	endRed = _endRed;
	endGreen = _endGreen;
	endBlue = _endBlue;
}

// Set colours as CGColorRefs.
- (void) setColoursWithCGColors:(CGColorRef)color1:(CGColorRef)color2
{
	const CGFloat *startComponents = CGColorGetComponents(color1);
	const CGFloat *endComponents = CGColorGetComponents(color2);

	[self setColours:startComponents[0]:startComponents[1]:startComponents[2]:endComponents[0]:endComponents[1]:endComponents[2]];
}

- (void)dealloc
{
    [super dealloc];
}

@end

And the header file GradientView.h as so:

//
//  GradientView.h
//  evilrockhopper
//
//  Created by Daniel Wichett on 10/12/2009.
//

#import <UIKit/UIKit.h>

@interface GradientView : UIView
{
    float startRed;
    float startGreen;
    float startBlue;

    float endRed;
    float endGreen;
    float endBlue;

    BOOL mirrored;
}

@property (nonatomic) BOOL mirrored;

- (void) setColoursWithCGColors:(CGColorRef)color1:(CGColorRef)color2;
- (void) setColours:(float) startRed:(float) startGreen:(float) startBlue:(float) endRed:(float) endGreen:(float)endBlue;

@end

So an example usage could be:

    GradientView *redToBlack = [[GradientView alloc] initWithFrame:CGRectMake(0,0,320,50)];
    [gradientBg setColoursWithCGColors:[UIColor colorWithRed:1.0 green:0.0 blue:0.0 alpha:1.0].CGColor:[UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:1.0].CGColor];

This creates a vertical gradient from red to black. If you wanted it to go from red to black to red, you can just set redToBlack.mirrored = YES.

It currently ignores the alpha value of the colours passed in, this would be trivial to add of course if required. If you want to experiment with other types of gradients, read the documentation for CGGradientCreateWithColorComponents. Feel free to use the code above, you can download the source by clicking on the menu in the top right of each code snippet.

iPhone Development – XCode quirks, bugs and provisioning problems

Although XCode is not the worst IDE in the world, it is definitely buggy.

Countless times I have come up against a bug, almost always to do with provisioning profiles, build failures or sync issues which make no sense whatsoever. To prevent you banging your head constantly against a wall, when a problem seems totally illogical I always take these steps.

  1. Stop the app
  2. Delete from the device / simulator as appropriate
  3. Restart XCode
  4. Clean all builds
  5. Pray

If that doesn’t work:

  1. As above
  2. Restart Mac
  3. Restart iPhone

Trust me, more often than not that will fix all sorts of problems.