Refactoring Moving 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 project I 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 File Add 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 code If there were local variables, make them instance variables See next slide
XXXViewController.h #import #import "alien.h” static const int NUMALIENS = CMPViewController :UIViewController{ alien *george, *sally; double timeToHome; double timeToPlace; double theSpeed; double theDistance; id 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 UITextFields You’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
IBActions Fill 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; 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 properties, their getters and setters are preceded by an underscore (‘_’)
Fix the keyboard Connect 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 full UIAlertView *alert = [[UIAlertView alloc] Alert!" many Aliens!" delegate:nil 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 Buttons Add components to perform other functions from the console app
Connect the new components I 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 timeHome]; } If you don’t properties, their getters and setters are preceded by an underscore (‘_’)