Servin Mobile Software


iPhone™ Programming: UIDevice


Norman McEntire

Version 1.7 May 12. Thank you Pierre M.

Version 1.6 May 11. Thank you Pierre M.

Version 1.5 May 1. Thank you Pierre M.

Version 1.4 April 30. Thank you Pierre M.

Version 1.3 January 28

Copyright © 2009 Servin Corporation. http://servin.com


About iPhone UIDevice

The UIDevice is a class that provides information about the iPhone or iPod Touch device.

Some of the information provided by UIDevice is static, such as device name or system version.

Other information, such as the device orientation information, is dynamic. It gives current status as to whether the device is face up, face down, in portrait or in landscape orientation.

In this tutorial, you will learn how to use the UIDevice class.


Sample Run on iPhone Simulator

At the end of this tutorial, if you run this app on the iPhone Simulator, it will appear like this:


iPhone Software Skills You Will Learn


Prerequisites


Startup Xcode

If Xcode is not already running, start it up:

  1. On the Mac Desktop, double-click on the Finder icon (the icon with the face on it).
  2. On the left-side of the Finder window, click on Macintosh HD.
  3. On the right-side of the Finder window, click on the Developer folder.
  4. Click on the Applications folder.
  5. Double-click on the Xcode icon.

At this point, you should see the Xcode menu at the top of your desktop.


Create New Xcode Project

With Xcode running, create a new Xcode project:

  1. File > New Project
  2. On the left-side of the New Project window, select Application under iPhone OS.
  3. On the right-side of the New Project window, select Tab Based Application.
  4. Click on the Choose button.
  5. Enter DeviceInfo for the project name.
  6. Click on Save button.

At this point, you should see Xcode open a new window that shows a number of files.


Build Default App

Go ahead and build the default application:

  1. Press the Build and Go button.
  2. After a brief moment, you should see the code running in the iPhone Simulator.
  3. Observe that the "First View" and the "Second View" tab buttons.
  4. In the iPhone Simulator, press the Home button to stop the application.

Use Interface Builder to Edit MainWindow.xib

In this exercise, you will use Interface Builder to edit MainWindow.xib, changing the names of the tabbed buttons to "Device Info" and "Orientation".

  1. In Xcode, in the Groups & Files window on the left, click on the Resources folder to view a list of source files.
  2. Double-click on MainWindow.xib, which starts up Interface Builder.
  3. Click on the title of the window titled "Tab Bar Controller".
  4. From the Interface Builder menu, select Tools > Attributes Inspector.
  5. Where the title says "First", double-click and change the title to say "Device Info".
  6. Where the title says "Second", double-click and change the title to say "Orientation".
  7. In the window titled "Tab Bar Controller", select the "First View" text, and delete it.
  8. Select the "Optionally move this view..." text and delete it.
  9. In the Interface Builder menu, select Tools > Library to display the "Library" window.
  10. In the "Library" window, select "Data Views".
  11. Drag the "Table View" controller onto the "Tab Bar Controller" window.
  12. In the Interface Builder menu, select File > Save.
  13. Press Command+Tab to return to Xcode.
  14. In Xcode, double-click on SecondView.xib.
  15. Observe that a view window opens, showing "Second View".
  16. Delete the text labeled "Loaded by the Second View Controller....".
  17. Change the "Second View" text to read "Orientation View".
  18. In the Interface Builder menu, select File > Save.
  19. Press Command+Tab and return to Xcode.
  20. Click on Build and Go.
  21. Your code should run with two tabs, one labeled "Device Info" and the other labeled "Orientation".

  22. Press Home on iPhone Simulator to exit the application.

As a review, in this exercise you used Interface Builder to customize the user-interface for a "Device Info" view and a "Orientation" view.


Add UITableView to FirstViewController

In this exercise, you will edit the FirstViewController class so that it can manage the UITableView. As you will see, this includes adding the UITableViewDataSource protocol to the FirstViewController class.

  1. In Xcode, in the Groups & Files window on the left, click on the Classes folder to view a list of source files:
    DeviceInfoAppDelegate.h
    DeviceInfoAppDelegate.m
    FirstViewController.h
    FirstViewController.m
    
  2. Click on FirstViewController.h to select the file into the Xcode editor.
  3. Edit the code as follows:
    #import <UIKit/UIKit.h>
    
    @interface FirstViewController : UIViewController <UITableViewDataSource> {
    	UITableView *tableView;
    
    }
    
    @property (nonatomic, retain) IBOutlet UITableView *tableView;
    
    @end
    
  4. The UITableViewDataSource is a protocol (a set of functions) that the FirstViewController can implement to work with a UITableView. If you are a Java software developer, the UITableViewDataSource is an interface in Java terminology; it is a protocol in Objective-C terminology.
  5. The IBOutlet tells Interface Builder that this tableView variable will be associated with a UITableView that is part of the user-interface of the first view.
  6. Select FirstViewController.m into the editor.
  7. Enhance the code to match the following:
    #import "FirstViewController.h"
    
    @implementation FirstViewController
    
    @synthesize tableView;
    
    - (void)viewDidLoad {
    	[super viewDidLoad];
    
    	self.tableView.dataSource = self;
    }
    
    
  8. Every table view (UITableView) requires a data source, which is an object that provides data to the table. In this case, the data source is set to the class itself.
  9. To implement the UITableViewDataSource protocol, you must implement at least these two methods:
    tableView:numberOfRowsInSection:
    tableView:cellForRowAtIndexPath:
    
  10. Continue to edit FirstViewController.m, adding code to implement the tableView:numberOfRowsInSection: method.
  11. 
    - (NSInteger)tableView:(UITableView *)tableView
    	 numberOfRowsInSection:(NSInteger)section {
    
    	return 1; //Temporary - will change later
    
    }
    
    
  12. Continue to edit FirstViewController.m, adding code to implement the tableView:cellForRowAtIndexPath: method.
    
    - (UITableViewCell *)tableView:(UITableView *)tableView
    	 cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    	UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"any"];
    	if (cell == nil) {
    		cell = [[[UITableViewCell alloc]
    			 initWithFrame:CGRectZero reuseIdentifier:@"any"]
    			autorelease];
    	}
    	cell.text = @"TODO";
    	return cell;
    
    }
    
    

As a review, in this exercise you added code to FirstViewController, so that it can manage the UITableView.


Use Interface Builder to Connect UITableView Data Source

In this exercise, you will use Interface Builder to connect the data source of the UITableView to the FirstViewController.

  1. Press Command+Tab to return to Interface Builder.
  2. Click on the Table View to select.
  3. Control-click on the Table View, observing that a Table View window appears.
  4. Press and hold the Control button, then click and drag from the "o" for dataSource to the MainWindow.xib, dropping on the FirstViewController (in the Type column).
  5. The result of the previous control-click-drag is that the Table View is connected to the FirstViewController. To repeat: Once you have completed the control-click-drag, the UITableView control shown by Interface Builder is now connected to the FirstViewController.
  6. Select File > Save in Interface Builder.
  7. Press Command-Tab to return to Xcode.
  8. Select Build and Go in the Xcode menu to build and run your app.
  9. You should see a "TODO" message displayed in the Table View.
  10. Press Home to exit your application.

As a review, in this exercise you used Interface Builder to control-click-drag from the UITableView control to the FirstViewController.


Use UIDevice For Device Info

In this exercise, you will edit the FirstViewController class so that it adds info provided by UIDevice to the UITable.

  1. In Xcode, select FirstViewController.h into the editor.
  2. Edit the code to match the following:
    #import <UIKit/UIKit.h>
    @interface FirstViewController : UIViewController <UITableViewDataSource> {
    	UITableView *tableView
    
    	NSArray *propertyNames;
    
    }
    @property (nonatomic, retain) IBOutlet UITableView *tableView;
    
    @property (nonatomic, retain) NSArray *propertyNames;
    
    @end
    
  3. The code adds a member variable named propertyNames, which is a pointer to a NSArray.
  4. Select FistViewController.m into the editor.
  5. Edit the code to match the following.
    #import "FirstViewController.h"
    
    @implementation FirstViewController
    
    @synthesize tableView;
    
    @synthesize propertyNames;
    
    
    - (void)viewDidLoad {
    	[super viewDidLoad];
    
    	self.tableView.dataSource = self;
    
    	self.propertyNames = [[NSArray alloc]
    			    initWithObjects:@"model",
    				 @"name",
    				 @"systemName",
    				 @"systemVersion",
    				 nil];
    
    }
    
  6. The code above initializes the array with the names of the properties.
  7. Continue to edit the code so that tableView:numberOfRowsInSection: returns the count of elements in the array.
  8. - (NSInteger)tableView:(UITableView *)tableView
    	 numberOfRowsInSection:(NSInteger)section {
    
    	return self.propertyNames.count;
    
    }
    
  9. Continue to edit FirstViewController.m, adding code to implement the tableView:cellForRowAtIndexPath: method.
    - (UITableViewCell *)tableView:(UITableView *)tableView
    	cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    
    	UITableViewCell *cell = [self.tableView dequeueReusableCellWithIdentifier:@"any"];
    	if (cell == nil) {
    		cell = [[[UITableViewCell alloc]
    			 initWithFrame:CGRectZero reuseIdentifier:@"any"]
    			autorelease];
    
    		NSString *value;
    		switch (indexPath.row) {
    			case 0: value = [[UIDevice currentDevice] model]; break;
    			case 1: value = [[UIDevice currentDevice] name]; break;
    			case 2: value = [[UIDevice currentDevice] systemName]; break;
    			case 3: value = [[UIDevice currentDevice] systemVersion]; break;
    		}
    	
    		CGRect rect = CGRectMake(10.0, 0.0, 120.0, 40.0);
    		UILabel *name = [[UILabel alloc] initWithFrame:rect];
    		name.text = [self.propertyNames objectAtIndex:indexPath.row];
    		[cell addSubview:name];
    
    		rect = CGRectMake(160.0, 0.0, 200.0, 40.0);
    		name = [[UILabel alloc] initWithFrame:rect];
    		name.text = value;
    		[cell addSubview:name];
    	}
    
    	return cell;
    }
    
  10. Build and Go.
  11. Here is device info as displayed on the iPhone Simulator:
  12. Here is device info as displayed on the iPod Touch:

As a review, in this exercise you added code to FirstViewController, so that it could display UIDevice properties.


Create OrientationViewController Class

In this exercise, you will create a class named OrientationViewController. This class will be similar to the FirstViewController class; it will be in charge of handling the view when the user presses the "Orientation" tab.

  1. In Xcode, select the Classes folder.
  2. Control-Click on the Classes folder, then select Add > New File.
  3. When you see the "New File" window, select Cocoa Touch Classes on the left-side of the window.
  4. Select UIViewController subclass on the right-side of the window.
  5. Click on Next.
  6. Name the file OrientationViewController.
  7. Click Finish.
  8. At this point you have two new files added to your project:
    OrientationViewController.h
    OrientationViewController.m
    
  9. Select OrientationViewController.h into the editor.
  10. Edit the code to match the following.
    #import <UIKit/UIKit.h>
    
    @interface OrientationViewController : UIViewController {
    
    	UILabel *orientationMsg;
    
    }
    
    @property (nonatomic, retain) IBOutlet UILabel *orientationMsg;
    - (void)doTimer:(NSTimer *)theTimer;
    
    @end
    
  11. Similar to what you did with the UITableView control, the code in the previous step will give you access to the UILabel control that is laid out by Interface Builder. You need access to the label so that you can change the text; for example, change it from saying "Portrait" to "Landscape" as you rotate the device.
  12. The doTimer: will be used as the timer function.
  13. Select OrientationViewController.m into the editor.
  14. Edit the code to match the following.
    #import "OrientationViewController.h"
    
    @implementation OrientationViewController
    
    @synthesize orientationMsg;
    
    - (void)doTimer:(NSTimer *)theTimer {
    	// Get orientation
    	UIDeviceOrientation o = [[UIDevice currentDevice] orientation];
    
    	// Change message based on orientation
    	switch (o) {
    		case UIDeviceOrientationUnknown:
    			self.orientationMsg.text = @"Orientation Unknown";
    			break;
    
    		case UIDeviceOrientationPortrait:
    			self.orientationMsg.text = @"Orientation Portrait";
    			break;
    		case UIDeviceOrientationPortraitUpsideDown:
    			self.orientationMsg.text = @"Portrait Upside Down";
    			break;
    
    		case UIDeviceOrientationLandscapeLeft:
    			self.orientationMsg.text = @"Landscape Left";
    			break;
    		case UIDeviceOrientationLandscapeRight:
    			self.orientationMsg.text = @"Landscape Right";
    			break;
    
    		case UIDeviceOrientationFaceUp:
    			self.orientationMsg.text = @"Face Up";
    			break;
    		case UIDeviceOrientationFaceDown:
    			self.orientationMsg.text = @"Face Down";
    			break;
    
    		default:
    			self.orientationMsg.text = @"?";
    	}
    }
    
    
  15. The code in the previous step gets the current device orientation from UIDevice, and then updates the label based on the value.
  16. Continue to edit the code:
    
    - (void)viewDidLoad {
    	[super viewDidLoad];
    
    	// Startup orientation notifications
    	[[UIDevice currentDevice]
    	 beginGeneratingDeviceOrientationNotifications];
    
    	// Setup timer to check for orientation status
    	[NSTimer scheduledTimerWithTimeInterval:1.0
    		  target:self
    		  selector:@selector(doTimer:)
    		  userInfo:nil
    		  repeats:YES];
    }
    
    
  17. The code from the previous step enables the orientation notifications. It also sets up a time to check the notification status every second.
  18. Continue to edit the code:
  19. - (void)dealloc {
    
    	[[UIDevice currentDevice]
    	 endGeneratingDeviceOrientationNotifications];
    
    	[super dealloc];
    }
    
  20. The code in the previous step disabled the device orientation notifications.
  21. Build and Go.
  22. You should observe that no visual changes have occurred to your application. That is, when you touch the "Orientation" tab, you still see the "Orientation View" message. This is because you still need to use Interface Builder to connect this class you created with the view controller.

As a review, in this exercise you created a new class named OrientationViewController. The purpose of this class is to enable/disable the orientation notifications, and to display the current orientation in the view.


Use Interface Builder to Connect OrientationViewController

In this exercise, you will use Interface Builder to connect the OrientationViewController class to the "second" view.

  1. In Xcode select the Resources folder.
  2. Double-click on SecondView.xib to open the file in Interface Builder.
  3. In Interface Builder, find the window titled SecondView.xib. If it is not visible, select Window > SecondView.xib to view.
  4. Select Tools > Identity Inspector, observing that the value of "Class" at the top of the window is set to UIViewController.
  5. Change the name of the class from UIViewController to OrientationViewController. To repeat: Change the name of the "Class" from UIViewController to OrientationViewController. This is the key step for connecting your OrientationViewController code to this view controller.
  6. Use the Interface Builder menu to select Window > MainWindow.xib.
  7. Expand the "Tab Bar Controller as needed, and select View Controller (Orientation), observing that it has the type of UIViewController.
  8. Select Tools > Identity Inspector, observing that the value of "Class" is UIViewController.
  9. Change the value of "Class" from UIViewController to OrientationViewController.
  10. To repeat: You changed the value of UIViewController to OrientationViewController in both MainWindow.xib and SecondViewController.xib.
  11. Select File > Save in Interface Builder.
  12. Press Command-Tab to return to Xcode.
  13. Select Build and Go in the Xcode menu to build and run your app.
  14. Again, you will not see any visible changes to your app. Although you have associated the class with the view controller, you have not yet connected the IBOutlet.
  15. Press Home to exit your application.
  16. To connect the IBOutlet, press Command+Tab to return to Interface Builder.
  17. In the SecondView.xib window, Control-Click on File's Owner, which displays the window of Outlets.
  18. Control-Click-Drag from the "O" associated with the orientationMsg to the "Orientation View" label that is on the window labeled "View". This is an important step: it connects the orientationMsg outlet to the actual UILabel, hence allowing you to change the value of the label under program control.
  19. Select File > Save in Interface Builder.
  20. Press Command-Tab to return to Xcode.
  21. Select Build and Go in the Xcode menu to build and run your app.
  22. Now have some fun! Install on your iPhone or iPod Touch, and have fun positioning the device various ways, face up, face down, portrait, landscape --- you'll see the message displayed in the screen!

As a review, in this exercise you used Interface Builder to connect your OrientationViewController class with the SecondView.xib.


Skills Review


How To Contact Author

Feel free to contact the author for any of the following:


Updated 2009 May 12
Content viewable on all web browsers, including smart mobile phone devices.
Copyright © 1995-2009 Servin Corporation. All rights reserved.