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




12 comments:

Gargs said...

This is definitely going to be very helpful in future projects. Thanks!

Greg Meach said...

Thanks Jeff

My anal side is going to show..... for those other noobs like me:

Replace #import "UIDeviceHardware.h" with #import "UIDevice-Platform.h"
Add a "[" just before the second platform in the bluetooth return line

:-)
Sorry previous post had a typo...

Neil Mix said...

Extra credit: forward compatibility -- if the hardware isn't found, look it up via a well-known URL and persist on the device.

Jonah said...

I think it is worth pointing out that Apple tries to strongly discourage you from checking for device model when you can check for the specific features you need.

For example if you want to know if the device has a camera then check to see if it has a camera, not if it is an iPhone.

There are some features you cannot detect individually but at least try to detect the feature before falling back to device model.

You can also use "[UIDevice currentDevice].model" if you don't care about the device version numbers.

Jeff LaMarche said...

Jonah:

There are times when it becomes important, however, and Apple doesn't provide a mechanism. For example, if you're implementing GameKit, but NOT using the built in Peer finder (and there are many valid reasons why you wouldn't). In those cases, you have to know what platform you're running on.

You are right, that if there is a mechanism provided, the way the Camera does, or if a framework hides the details from you, the way Core Location does, then you shouldn't be using this.

Jeff LaMarche said...

Greg:

Whoops! Yep, was in a hurry and didn't compile before posting. I have fixed the post. Thanks for catching that.

Jeff

Daniel said...

thanks, it works great. except that iPod Touch is actually spelled iPod touch

Orville Chomer said...

One thing I don't like is that when you used the iPhone Simulator, it returns an iPhone Simulator string. It is my opinion that it should Not do that!
Rather, the simulator should give you the ability to pick between simulating the Phone or the iPod touch. There should be a completely different way to check if you are using the simulator for running debugging code.

TechMan said...

I replaced the depreciated call to stringWithCString
NSString *platform = [NSString stringWithCString:machine];

with

NSString *platform = [[NSString alloc ]initWithUTF8String:machine];

Edwin said...

scrub m65 kamagra attorney lawyer body scrub field jacket lovegra marijuana attorney injury lawyer

SEO Services Consultants said...

Nice information, many thanks to the author. It is incomprehensible to me now, but in general, the usefulness and significance is overwhelming. Thanks again and good luck! Web Design Company

h4ns said...

What youre saying is completely true. I know that everybody must say the same thing, but I just think that you put it in a way that everyone can understand. I also love the images you put in here. They fit so well with what youre trying to say. Im sure youll reach so many people with what youve got to say.

Arsenal vs Huddersfield Town live streaming
Arsenal vs Huddersfield Town live streaming
Wolverhampton Wanderers vs Stoke City Live Streaming
Wolverhampton Wanderers vs Stoke City Live Streaming
Notts County vs Manchester City Live Streaming
Notts County vs Manchester City Live Streaming
Bologna vs AS Roma Live Streaming
Bologna vs AS Roma Live Streaming
Juventus vs Udinese Live Streaming
Juventus vs Udinese Live Streaming
Napoli vs Sampdoria Live Streaming
Napoli vs Sampdoria Live Streaming
Fulham vs Tottenham Hotspur Live Streaming
Fulham vs Tottenham Hotspur Live Streaming
AS Monaco vs Marseille Live Streaming
AS Monaco vs Marseille Live Streaming
Alajuelense vs Perez Zeledon Live Streaming
Alajuelense vs Perez Zeledon Live Streaming
Technology News | News Today | Live Streaming TV Channels