Friday, October 16, 2009

Device Detection Redux

A while back, I posted some code by Max Horáth to detect the device your program was running on. That script dates from the pre-3Gs days, so won't identify that model. I'm not sure if Max has updated his script, but I found this class on Stack Overflow by Jason Goldberg. In addition to adding the more recent hardware, it uses a really efficient approach implemented in relatively few lines of code. I like that a lot.

The one thing I don't like is the way the class is implemented. There's no reason to use instance methods like this and incur the overhead of object creation to. The object has no state, just behavior, so either of these methods could have been written either as C functions or as class methods, thus avoiding the need to create an object and manage its memory. At very least, this class should have been implemented as a singleton.

Anyone who's been reading my blog probably knows where I'm going here. In my ever-so-humble opinion, the best approach for this functionality have been to write it as a category on UIDevice, like so:

UIDevice-Platform.h
#import <Foundation/Foundation.h>

@interface UIDevice (platform)

- (NSString *) platform;
- (NSString *) platformString;

@end

UIDevice-Platform.m
#import "UIDevice-Platform.h"
#include <sys/types.h>
#include <sys/sysctl.h>

@implementation UIDevice (platform)

- (NSString *) platform{
size_t size;
sysctlbyname("hw.machine", NULL, &size, NULL, 0);
char *machine = malloc(size);
sysctlbyname("hw.machine", machine, &size, NULL, 0);
NSString *platform = [NSString stringWithCString:machine];
free(machine);
return platform;
}

- (NSString *) platformString{
NSString *platform = [self platform];
if ([platform isEqualToString:@"iPhone1,1"]) return @"iPhone 1G";
if ([platform isEqualToString:@"iPhone1,2"]) return @"iPhone 3G";
if ([platform isEqualToString:@"iPhone2,1"]) return @"iPhone 3GS";
if ([platform isEqualToString:@"iPod1,1"]) return @"iPod Touch 1G";
if ([platform isEqualToString:@"iPod2,1"]) return @"iPod Touch 2G";
if ([platform isEqualToString:@"i386"]) return @"iPhone Simulator";
return platform;
}

- (BOOL)supportsBluetoothNetworking {
NSString *platform = [self platform];
return !([platform isEqualToString:@"iPhone1,1"] || platform isEqualToString:@"iPod1,1"]);
}

@end

No comments:

Post a Comment