Determine Device Type – 3G or 3GS / iPod First or Second Generation
Using the UIDevice class, you can figure out if your application is running on a iPod or an iPhone. To get this information, access the property named model which will return an NSString of iPhone or iPod touch. However, there may be times when you need more specifics, for example is the iPhone the latest device, a 3GS or on the flip side, is the iPod a first or second generation device?
Accessing the system hardware will reveal the information we need to make the above distinctions. We’ll use a category to extend the UIDevice class with a method that returns the “machine” type as a string. Begin with the interface definition below:
@interface UIDevice(machine) - (NSString *)machine; @end
To access the hardware type we’ll call a function in the standard C library:
sysctlbyname(const char *name, void *oldp, size_t *oldlenp, void *newp, size_t newlen);
The first parameter is the name of the system information we are after. The information will be copied into the buffer ‘oldp’ and we specify the size of this buffer in the ‘oldlenp’ parameter. We set ‘newp’ to NULL as this is for setting a value (versus getting a value). On a similar note, we set ‘newlen’ to 0, as that is reserved for calls to set information.
Putting all that together into, the implementation of our class looks as follows:
#import "UIDevice+machine.h" #include <sys/types.h> #include <sys/sysctl.h> @implementation UIDevice(machine) - (NSString *)machine { size_t size; // Set 'oldp' parameter to NULL to get the size of the data // returned so we can allocate appropriate amount of space sysctlbyname("hw.machine", NULL, &size, NULL, 0); // Allocate the space to store name char *name = malloc(size); // Get the platform name sysctlbyname("hw.machine", name, &size, NULL, 0); // Place name into a string NSString *machine = [NSString stringWithCString:name]; // Done with this free(name); return machine; } @end
We can now call the new method as follows:
#import "UIDevice+machine.h" ... NSLog(@"device: %@", [[UIDevice currentDevice] machine]);
The return values will be as follows:
- iPhone Simulator == i386
- iPhone == iPhone1,1
- 3G iPhone == iPhone1,2
- 3GS iPhone == iPhone2,1
- 4 iPhone == iPhone3,1
- 1st Gen iPod == iPod1,1
- 2nd Gen iPod == iPod2,1
- 3rd Gen iPod == iPod3,1
The following images show the output in Xcode (running in the simulator) and on my 3G iphone:










Thanks for this. I was looking how to do this but never quite got there – thought it would be something that was available in the normal SDK without having to dig about in sysctl.
Yeah, Thanks John.
Could you possibly upload the project file, so that others can dig deeper into the code, settings, etc.
Thanks!
Terrance
Hi Terrance,
Using the code is as easy as creating a new file with the name UIDevice+machine.h and add the interface definition shown above. Then create another file: UIDevice+machine.m and paste in the implementation code. Save these files and import into your project (or you can create the files within Xcode).
To use the new class, add #import “UIDevice+machine.h” to your class and call [[UIDevice currentDevice] machine]
John
Thank you verrrry much.
Excellent!
Thanks again John!
Terrance
Thanks for this. Was googling around for a solution and yours was the simplest, and it works.
Thank you for this. You’re a genius :)
Thanks for a great tutorial
Is this App Store Safe?
/Olof
olof, this could does not use private api’s so I assume there are no worries regarding app approval
Great! Thanks for sharing this code.
/Olof
Updated device list:
iPhone Simulator == i386
iPhone == iPhone1,1
3G iPhone == iPhone1,2
3GS iPhone == iPhone2,1
1st Gen iPod == iPod1,1
2nd Gen iPod == iPod2,1
1st Gen iPad == iPad1,1
iPhone 4 == iPhone3,1
I imagine the iPod Touch 4 will be == iPod3,1
and the 2011 next generation iPad will be == iPad2,1