Translate

Tuesday, April 17, 2012

Is Application Running on iPhone or iPod touch

If you ever need to know whether your application is running on an iPod touch or an iPhone, the answer is as close as this one line of code:

NSString *deviceType = [UIDevice currentDevice].model;

To get the model of the device as a localized string:

NSString *deviceType = [UIDevice currentDevice].modellocalizedModel;
NSLog(@"type: %@", deviceType);

One use could be to customize messages shown within your applications, for example:

float version = 1.1;
...
NSString *deviceType = [UIDevice currentDevice].model;
NSLog(@"Your %@ has version %2.1f of Today's Horoscope installed.",
deviceType, version);

Here’s the output from both of the code snippets is shown below:

Query the Battery State and Level of Charge

There are times when checking in on the battery status can be a good idea. The code that follows shows how to monitor battery states and levels (percent of charge) using methods in the UIDevice class.
Enable Battery Monitor

To query information regarding the iPhone battery status, you start by enabling battery monitoring through a call in the UIDevice class. With enabling active, you can then get the battery level and state (e.g. charging, discharging, etc):

[[UIDevice currentDevice] setBatteryMonitoringEnabled:YES];

[[UIDevice currentDevice] batteryLevel];
[[UIDevice currentDevice] batteryState];

Notification of Battery Changes

You can monitor on going battery changes by registering to receive notifications of battery level and status updates:

// Request to be notified when battery charge or state changes
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(batteryStatus) name:UIDeviceBatteryLevelDidChangeNotification object:nil];

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(batteryStatus) name:UIDeviceBatteryStateDidChangeNotification object:nil];

Changes in the battery level/state will result in a call to the method batteryStatus, where you can update a visual que or otherwise handle changes.
Display Battery Status

To test the battery status I’ve written a simply view controller that has nothing more than a textview, where the current status and level are displayed.

There are two relevant sections of code for this application, the first is within the loadView method where I setup a textview, enable battery monitoring and add observers for the two notifications I am interested in:

- (void)loadView
{
[self setView:[[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease]];

// Setup the textview to display battery status
textViewStatus = [[UITextView alloc] initWithFrame:CGRectMake (20, 20, 280, 64)];
[textViewStatus setFont:[UIFont boldSystemFontOfSize:18.0]];
[textViewStatus setEditable:NO];
[textViewStatus setTextAlignment:UITextAlignmentCenter];
[[self view] addSubview:textViewStatus];

// Round the corners and set border color
[textViewStatus setBackgroundColor:[UIColor whiteColor]];
[[textViewStatus layer] setBorderColor:[[UIColor blueColor] CGColor]];
[[textViewStatus layer] setBorderWidth:2.3];
[[textViewStatus layer] setCornerRadius:15];
[textViewStatus setClipsToBounds: YES];

// Enable monitoring of battery status
[[UIDevice currentDevice] setBatteryMonitoringEnabled:YES];

// Print current status
[self batteryStatus];

// Request to be notified when battery charge or state changes
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(batteryStatus) name:UIDeviceBatteryLevelDidChangeNotification object:nil];

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(batteryStatus) name:UIDeviceBatteryStateDidChangeNotification object:nil];

}

The second method of interest is batteryStatus, which is the other end of the notification requests, that is, the method called via the OS when the battery status or level changes:

- (void)batteryStatus
{
NSArray *batteryStatus = [NSArray arrayWithObjects:
@"Battery status is unknown.",
@"Battery is in use (discharging).",
@"Battery is charging.",
@"Battery is fully charged.", nil];

if ([[UIDevice currentDevice] batteryState] == UIDeviceBatteryStateUnknown)
{
[textViewStatus setText:[batteryStatus objectAtIndex:0]];
NSLog(@"%@", [batteryStatus objectAtIndex:0]);
}
else
{
NSString *msg = [NSString stringWithFormat:
@"Battery charge level: %0.2f%%\n%@", [[UIDevice currentDevice] batteryLevel] * 100,
[batteryStatus objectAtIndex:[[UIDevice currentDevice] batteryState]] ];

[textViewStatus setText:msg];
NSLog(@"%@", msg);
}
}

Notes

The battery status returned from the API’s above may not always be in sync with the status displayed on device – notice in the screenshot above that the device status is different than what is displayed in the textview (bug or feature, I’m not certain).

Also, Apple recommends that you enable battery monitoring only when your application needs to be notified of changes versus leaving enabling monitoring during the entire lifecycle of your app.

Xcode Project Source Code

Download Xcode Project: iphonedevelopertips.com/wp-content/uploads/2011/01/BatteryStatusIndicator.zip

Get iPhone Device Name, Unique Device Identifier (UDID), OS and Model

The iPhone SDK includes a singleton of class type UIDevice that you can use to retrieve device specific information (this works equally as well with the simulator).
Available Properties in UIDevice

uniqueIdentifier – identifier guaranteed to be unique for every device
name – arbitrary name found in General > About setting on device
systemName – name of the OS running on the device
systemVersion – current version of the OS
model- model, such as ”iPhone” or ”iPod touch”
localizedModel – same as above using a localized string

Stats for Simulator

This code will list all stats shown above:

NSLog(@"uniqueIdentifier: %@", [[UIDevice currentDevice] uniqueIdentifier]);
NSLog(@"name: %@", [[UIDevice currentDevice] name]);
NSLog(@"systemName: %@", [[UIDevice currentDevice] systemName]);
NSLog(@"systemVersion: %@", [[UIDevice currentDevice] systemVersion]);
NSLog(@"model: %@", [[UIDevice currentDevice] model]);
NSLog(@"localizedModel: %@", [[UIDevice currentDevice] localizedModel]);

Running the above on the simulator returns:

Stats for iPhone

The device stats when running on my iPhone:

Using the Proximity Sensor

The proximity sensor on the iPhone detects when the device is close to your face (or otherwise covered). There aren’t many times when using the sensor is of value, however, the Google Voice Search application has put this to good use as a means to trigger voice recording for a search request. If you have an interest in doing something similar, read on.
Proximity Sensor Monitoring

It all begins by enabling proximity monitoring, this is followed by setting up a notification request to call a method when the proximity state changes:

// Enabled monitoring of the sensor
[[UIDevice currentDevice] setProximityMonitoringEnabled:YES];

// Set up an observer for proximity changes
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sensorStateChange:)
name:@"UIDeviceProximityStateDidChangeNotification" object:nil];

The method below will be called when the sensor state is updated, a message is printed to the debug console based on the sensor proximity.

- (void)sensorStateChange:(NSNotificationCenter *)notification
{
if ([[UIDevice currentDevice] proximityState] == YES)
NSLog(@"Device is close to user.");
else
NSLog(@"Device is ~not~ closer to user.");
}

Detecting Proximity Sensor

Not all iOS device have proximity sensors. The Apple API documentation states that you should enable proximity monitoring and check the proximityState, if the return value is NO, then the device does not have a sensor.

I was unable to successfully use this approach to determine if a device has a sensor. Any additional ideas or suggestions are welcome.

Check If App Is Running On An iPad

Check the userInterfaceIdiom property of the device to get the information you need:

- (BOOL)isDeviceiPad
{
BOOL iPadDevice = NO;

// Is userInterfaceIdiom available?
if ([[UIDevice currentDevice] respondsToSelector:@selector(userInterfaceIdiom)])
{
// Is device an iPad?
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad)
iPadDevice = YES;
}

return iPadDevice;
}

As noted in the comments below, Apple provides a macro to accomplish the same task. Here is the full definition from the UIDevice.h header file:

#define UI_USER_INTERFACE_IDIOM() ([[UIDevice currentDevice] respondsToSelector:@selector(userInterfaceIdiom)] ? [[UIDevice currentDevice] userInterfaceIdiom] : UIUserInterfaceIdiomPhone)