910 likes | 1.09k Views
Objective-C and iOS. Tony White ( arpwhite@scs.carleton.ca ) ( arpwhite@scs.carleton.ca ) Carleton University. Contents. Introduction Language Overview Building an app Model, view, controller Tic-tac-toe app. Introduction. Objective-C is: An object oriented language built around:
E N D
Objective-C and iOS Tony White (arpwhite@scs.carleton.ca) (arpwhite@scs.carleton.ca) Carleton University
Contents • Introduction • Language Overview • Building an app • Model, view, controller • Tic-tac-toe app
Introduction • Objective-C is: • An object oriented language built around: • Classes • Instances • Methods • Attributes • Specific to Apple • Extends C • Can develop for: • Mac OS X • iOS • Today we’ll talk about iOS • Learning by example
XCode • Is an integrated development environment (IDE) • Can develop command line and graphical user interfaces • We will focus on a graphical user interface with an underlying model • Allows an iPhone or an iPad to be simulated (with limitations)
The Single View Application • This is the simplest graphical user interface. • Corresponds to a basic screen on an iPhone app.
Naming the Project Give it a name
Specifying a Location Can have version control associated with project. Generally a good idea.
Project Files • AppDelegate .h, .m • ViewController .h, .m • Main_iPhone.storyboard • Main_iPad.storyboard • Supporting files: • Main.m • …
Code • Objective-C code is found in: • .h (specification or interface) • .m (implementation) • Properties can be found in: • .plist (property lists) • These are XML • The app is stored in the Products subdirectory. Its name is whatever name you gave it with a .app extension
AppDelegate • Provides access to the window representing the app (.h) • Provides a number of APIs to allow a developer to interact with the app throughout the lifecycle of the app. • Generally don’t need to modify this file (and certainly not during these lectures)
Main_X.storyboard • X = iPhone, iPad • These files allow a graphical user interface to be constructed using drag-and-drop interactions. • These files define the VIEW for the app (i.e., what we see on the device or in simulator).
ViewController • Defines the interface (.h) between the view described using Storyboard and the mechanisms for controlling it (e.g., mouse, trackpad, touch) • The implementation of the interface (.m) provides lifecycle APIs and methods for responding to events; e.g., button presses or user text field input.
main • This is the program entry point, equivalent to: • main.c in C, using int main(intargc, char *argv[]) • public static void main(String[] args) in Java • Generally don’t need to modify this.
Building Classes • Let’s deal with a real example. • We want to build a Tic-tac-toe app.
Modelling • To generate the game we’ll need 3 things: • A model • A view and • A controller • The Storyboard defines the view • We’ll need to create a model: a Game class • The ViewControllerimplements the controller
The Game Class: .h • #import • States what declarations/class definitions are to be included • Just like import statement in Java. • @interface Game : NSObject • Specifies the public attributes and public methods for the class • NSObject indicates the parent class (equivalent to Object in Java) • @property • Specifies an attribute for the class which is public • Have qualifiers; e.g., nonatomic, weak, strong • Attributes have a type; e.g., NSString, char or int • @end • Denotes end of interface specification
Class Attributes Each attribute has a type @property(nonatomic) boolhasStarted; @property(nonatomic) char currentTurn; @property(nonatomic) char winner; @property(strong) NSString *name; If the type is an object, the attribute name is preceded by a ‘*’. NSString is an example of a Foundation class. Each attribute has @property(…) associated with it
@property • Memory management is different from Java • Compiler explicitly includes allocation/deallocation calls – no garbage collection for iOS • Objective-C uses Automatic Reference Counting (ARC) • ARC is implemented on a per-module basis
@property • Have strong and weak attribute values • @property(strong) means that this instance is responsible for deallocation; i.e., when the instance is no longer referred to. • @property(weak) means that this instance is not responsible for memory deallocation; i.e., when instance disappears nothing is done for the attribute.
Game.h continued • Public methods can be declared too: • The ‘-’ indicates a instance method, a ‘+’ indicates a class method (i.e., like using static in Java as a method qualifier) -(void) placeMove: (char) token atPosition: (int) location; -(BOOL) isPlayer: (char) token; -(void) start; -(void) end; -(int) generateComputerMove;
Game.h continued • Public methods can be declared too: • The (void) after the ‘-’ indicates the return type of the method. -(void) placeMove: (char) token atPosition: (int) location; -(BOOL) isPlayer: (char) token; -(void) start; -(void) end; -(int) generateComputerMove;
Game.h continued • Public methods can be declared too: • If a method has arguments they will appear after the ‘:’ character; e.g., (char) token in the isPlayer: method. -(void) placeMove: (char) token atPosition: (int) location; -(BOOL) isPlayer: (char) token; -(void) start; -(void) end; -(int) generateComputerMove;
Game.h continued • Public methods can be declared too: • Methods with multiple arguments separate each argument with a keyword followed by a ‘:’. So, placeMove:atPosition is a 2-arg method. • Variable arg methods are also supported. -(void) placeMove: (char) token atPosition: (int) location; -(BOOL) isPlayer: (char) token; -(void) start; -(void) end; -(int) generateComputerMove;
Game.m • Implementation code is written in the .m file. • Can have private variables and methods. #import "Game.h” // Definitions and declarations @interface Game () // Can declare private variables and methods here @end @implementation Game // Code for methods goes here // Any static (class variables here too) … @end
Game.m Our Game class simulates another player so we need representations of the state of a tile on the board. @implementation Game char const static player = 'X'; char const static computer = 'O'; char const static empty = ' '; intconst static boardSize = 9; char boardValues[boardSize]; intwinCombos[8][3] = {{0,1,2},{0,3,6},{0,4,8}, {3,4,5},{1,4,7},{2,4,6}, {6,7,8},{2,5,8}}; The board – a simple array. Could do better! Corresponds to row, column and diagonal winning combinations
So, what does tic-tac-toe need? • Create a game object => constructor • Start and end the game • Making a move; i.e., changing the state of a tile. • Check whether a winning state has been achieved
Allocating an Object Game *game = [[Game alloc] init]; The alloc message actually allocates the space and maps the fields etc. onto that space. The init message (generally your code) is written like a Java zero argument constructor.
The constructor • Constructor is implemented in an init method • Equivalent to: “public Game() {}” in Java -(Game*) init { self = [super init]; if (self) { self.hasStarted = false; self.name= [NSStringstringWithFormat:@"Prof. White (%d)", rand()]; } return self; } NOTES: Always invoke the super class init method. The keyword super here means superclass. The keyword self here means the current instance.
The constructor • Constructor is implemented in an init method • Equivalent to: “public Game() {}” in Java -(Game*) init { self = [super init]; if (self) { self.hasStarted = false; self.name= [NSStringstringWithFormat:@"Prof. White (%d)", rand()]; } return self; } NOTES: [ NSString ….] is an objective-c call.
Sending messages … [NSStringstringWithFormat:@"Prof. White (%d)", rand()]; This means: Send the stringWithFormat: message to the NSString class. @”Prof. White (%d)” The @ symbol indicates that we are dealing with an object, in this case a String; i.e., an instance of the class NSString. All string literals are represented in this way. Here, we are creating a random number and using it to construct a name; the %d is interpreted just like String.format(…)
Starting a game -(void) start { // Indicate game in progress self.hasStarted = true; // Ensure that the board is empty for(int i = 0; i < boardSize; i++){ boardValues[i] = empty; } // Always have the human start self.currentTurn = player; // No one has won ... yet self.winner = empty; } Syntax for for loops and Access of attributes is very similar to Java
Ending a game/utility -(void) end { self.hasStarted = false; } // Testing whether a human is playing -(BOOL) isPlayer: (char)token{ return player == token; } // Switch from player to computer or vice versa -(void) togglePlayer{ If (self.currentTurn == player){ self.currentTurn= computer; } else { self.currentTurn = player; } }
Making a Move -(void) placeMove:(char)token atPosition:(int)location{ //Update the board boardValues[location] = token; //Switch the turn [self togglePlayer]; //Check to see if someone won if([self checkWin]) [self end]; }
Checking for a winner … -(BOOL) checkWin { // Iterate through the winning positions for(int i = 0; i < 8; i++){ if (boardValues[winCombos[i][0]] != empty && boardValues[winCombos[i][0]] == boardValues[winCombos[i][1]] && boardValues[winCombos[i][1]] == boardValues[winCombos[i][2]]){ self.winner= boardValues[winCombos[i][0]]; return true; } } // There wasn’t a winner so check for a draw return [self isDraw]; }
Summary • This is a simple implementation of a Game class • It uses arrays of primitives (chars and ints), not objects. • We can do better!
Implementing a Board • The Game should: • represent the Board explicitly • store moves. • So: • create a Board class • Game constructor will then construct a Board object.
Storing Moves • In order to store moves, we need a dynamically extensible array structure (like ArrayList in Java) • We use NSMutableArray for this.
NSArray/NSMutableArray • NSArray is an array object that can store arbitrary objects; however it cannot be modified once created. It is IMMUTABLE. • NSMutableArray can store arbitrary objects but can be modified after creation.
NSArray Creating an immutable array of names Ends with nil Accessing a specific object within the array General purpose logging facility
NSMutableArray NSMutableArray Example
NSMutableArray cont’d The array doesn’t have to contain objects of a single class; it can be heterogeneous Can just ask to remove an object too. I don’t have to know the index. Just use: removeObject: (id) object
References • NSArray and NSMutableArray • http://iphonelearning.wordpress.com/2011/08/24/nsarray-and-nsmutablearray/ • Learn Objective-C • http://cocoadevcentral.com/d/learn_objectivec/ • Ray Wenderlich’sexcellent tutorials: • http://www.raywenderlich.com/tutorials • My Mobile Apps course pages: • http://sikaman.dyndns.org:8888/courses/2601 • Look at lectures 13-23 for various apps
In-class Problem • Get TicTacToeXcode project from: http://sikaman.dyndns.org:8888/courses/csuci/TicTacToe.zip • Open project in Xcode by double clicking on the file Tic TacToe.xcodeproj. You can run it by clicking the arrow in the top left corner of the Xcode window. • You are to construct a Board class and modify the Game class to make use of it, replacing the primitive arrays that are used there. • Use only NSArray or NSMutableArray classes in both Game and Board classes. • Use NSLog to write out each move and to write out all of the moves when the game ends.
Enabling the Console From Xcode main pulldown menu: View>Debug Area>Activate Console You will then see all NSLog messages when app runs.