RefactoringMoving a console app to a UI app
Refactoring
Goal: change a console app to a UI app
Principles:The main.m goes away
The local variables in the main.m file become instance variables in the new viewController.m
The functions that implemented console interactions with the user become IBAction methods for various UI components
Other classes in the console app are imported as are to the UI app
For the code for these slides, see the class web site, References->Examples->AlienRefactored
Creating the project
Create new single view projectI named mine “alienRefactored”
You get the appDelegate and the ViewController.m
Now import the class files (but not the main.m file) from the old project
FileAdd Files to “AlienRefactored”
See next slide for the dialog box
Creating the project
Check this box
Choose the files
Main.m
Does not exist in the new project (that we can see)
Open main.m from the old project.
Use codeIf there were local variables, make them instance variables
See next slide
XXXViewController.h
#import <UIKit/UIKit.h>#import "alien.h”
static const int NUMALIENS = 2;
@interface CMPViewController :UIViewController{ alien *george, *sally; double timeToHome; double timeToPlace; double theSpeed; double theDistance; id theAliens[5];}@end
Import any class you use
Make constants that you need. These must be static
XXXViewController.h
- (void) viewDidLoad{ [super viewDidLoad];// Do any additional setup after loading the view, typically from a nib.
nextIndex = 0;
}
Use viewDidLoad method to initialize variables and initialize any dynamic memory.
Designing the interface
See where the console app asked for input
printf(“enter alien name:”);scanf(“%s”, theName);printf(“enter number of eyes:”);scanf(“%d”, numEyes);printf(“enter distance to home:”);scanf(“%f”, theDistance);printf(“enter speed of ship:”);scanf(“%f”, theSpeed);
These become UITextFieldsYou’ll need IBOutlets to access them in your code.
You’ll also need a button to determine when to add this alien
Interface
Connections
Create IBOutlets for the fields
Create IBAction for the button
IBActionsFill in the action methods
−(IBAction)addAlien:(UIButton *)sender { NSString *thePlanet = _nameField.text; theSpeed = [_speedField.text doubleValue]; theDistance = [_distanceField.text doubleValue]; int numEyes = [_numEyesField.text integerValue]; george =[[alien alloc] initWithNum: numEyes andDistance: theDistance
andPlanet: thePlanet]; if (nextIndex < 5) {
theAliens[nextIndex++] = george;
NSLog(@"the next alien lives at %@ and is %f miles from home at %f speed",
((alien *)theAliens[nextIndex - 1]).planet, ((alien *)theAliens[nextIndex - 1]).distanceToHome,
((alien *)theAliens[nextIndex - 1]).speedSpaceShip); }
}
Print to the console as an error check
If you don’t explicitly @synthesis properties, their getters and setters are preceded by an underscore (‘_’)
Fix the keyboardConnect to this method from every text field
Fix the keyboard
Add the action method for the text fields
−(IBAction)didFinishEditing:(UITextField *)sender {
[sender resignFirstResponder];
}
Put in appropriate error messages
Array is full in - (IBAction)addAlien:(UIButton *)sender if (nextIndex < MAXALIENS) {
// previous code else{
// the array is fullUIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Alien Alert!" message:@"Too many Aliens!" delegate:nil cancelButtonTitle:@"Phew!" otherButtonTitles:nil]; [alert show];
}
Add more buttons
Each console option must have a component (usually a button).
Add more buttons and fields as necessary.
Hide components to minimize clutter
More ButtonsAdd components to perform other functions from the console app
Connect the new componentsI would also add
an IBOutlet for the new field.
Add bodies for the Action methods
For our “Calc Time” button
- (IBAction)calcTimeHome:(UIButton *)sender { // pick an arbitrary alien
if (nextIndex > 0){ float timeHome = [((alien *)theAliens[0])
calcTimeToHome]; // put the value into the text field_timeToHome.text = [NSString stringWithFormat:
@"%f", timeHome]; }
}
If you don’t explicitly @synthesis properties, their getters and setters are preceded by an underscore (‘_’)