Sunday 10 April 2011

Determine Device

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:

 

 



How to get the hard disk size (capacity) of the iPad / iPod / iPhone your app is running on 

For an app we were developing I found myself needing to know the model and the disk capacity of the device the app was running on.
I found plenty of resource for identifying the device. The two methods appear to revolve around either testing the device for feature combinations known to appear on certain devices or using the sysctlbyname function in the standard C library.
Next was trying to find the capacity.  I could find very little information on this but eventually settled on this which worked well for me.

NSDictionary *fsAttr = [[NSFileManager defaultManager] attributesOfFileSystemForPath:NSHomeDirectory() error:nil];
float diskSize = [[fsAttr objectForKey:NSFileSystemSize] doubleValue] / 1000000000;
NSLog(@"Disk Size: %0.0f",diskSize);

2 comments: