iPhone sample code

I figured I would try out developing on Mac Os making an iPhone app. My first experience on the Hackintosh building an application ( my first blog post from it as well ). Anyway, I downloaded the SDK got xCode going and followed some Hello world tutorial. I feel Hello world is just too simple to get a feel for the environment and Objective-C. So I decided to port my HandiCap Android sample to the iPhone, should give me enough time to play with xCode and get a feel for it.

As I started up xCode and started coding first I noticed was the keyboard shortcuts which are strange when using PC keyboard on the Mac, I run the Mac in a VM. I understand I can map that anyway I want so that shouldn’t be a problem if I decide to do some more development. As I knew this sample was going to be short I didn’t bother changing it. When using xCode it doesn’t really feel like an IDE rather a collection of different tools. I had a hard time finding out how to set controls on a view in the beginning once I got the appropriate tools open it was pretty much straight forward. One thing that I don’t really understand is when you link controls to the File owner, why does that link your controls to your code view ? why not link that to the view itself as that is where the code resides ? I guess I will figure that out later as time goes on.

So let’s take a look at the code, first you need to reference the controls in the header file that you already setup in the Interface builder. Yes you need to do that by hand, it is not taken care of by the IDE, more integration is needed on the IDE’s behalf if you ask me. Note the UITextFieldDelegate tag on the controller, this one is needed to hide the keyboard when Return is pressed along with code in the class file.

#import <UIKit/UIKit.h>

@interface HandiCapViewController : UIViewController <UITextFieldDelegate>
{
       
        // First half
        IBOutlet UILabel *lbPlayer1;
        IBOutlet UITextField *txPlayer1;       
        IBOutlet UILabel *lbPlayer2;
        IBOutlet UITextField *txPlayer2;
       
        // Second half
        IBOutlet UILabel *lbWinPlayer1;
        IBOutlet UITextField *txWinPlayer1;
        IBOutlet UILabel *lbWinPlayer2;
        IBOutlet UITextField *txWinPlayer2;
}

(IBAction) btCalculate_Clicked:(id)sender;

@end

Then we start coding in the class ( .m ) file

#import "HandiCapViewController.h"
#include <tgmath.h>

@implementation HandiCapViewController

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
(void)viewDidLoad
{
    [super viewDidLoad];
       
        // Disable the two result fields
        txWinPlayer1.userInteractionEnabled = FALSE;
        txWinPlayer2.userInteractionEnabled = FALSE;
}

(void)didReceiveMemoryWarning {
        // Releases the view if it doesn’t have a superview.
    [super didReceiveMemoryWarning];
       
        // Release any cached data, images, etc that aren’t in use.
}

(void)viewDidUnload {
        // Release any retained subviews of the main view.
        // e.g. self.myOutlet = nil;
}

// Shut down the keyboard
(BOOL)textFieldShouldReturn:(UITextField *)textField
{
        NSLog( @“textFieldShouldReturn start”);
       
        // This code should be made dynamic instead of ugly if / else
        if( textField == txPlayer1 )
        {
                [txPlayer1 resignFirstResponder];
        }
        else if( textField == txPlayer2 )
        {
        [txPlayer2 resignFirstResponder];
        }

        return TRUE;
}

               
// Calculates handicap
(void) calculate:( double *) pdaPlayers;
{
        // STRONGER is lower handicap
        // See who is better rated coming in,
        Boolean bStrongerFirst =  pdaPlayers[0] < pdaPlayers[1];
        // Holds results
        double strong_race, weak_race;
       
        if( bStrongerFirst )
        {
                // What’s the race
                weak_race = MAX(2, 6floor( pdaPlayers[1] ));
                strong_race = weak_race + round( pdaPlayers[1] – pdaPlayers[0] );
                // set the slots before returning
                pdaPlayers[0] = strong_race;
                pdaPlayers[1] = weak_race;
        }
        else
        {
                // What’s the race
                weak_race = MAX(2, 6floor( pdaPlayers[0] ));
                strong_race = weak_race + round( pdaPlayers[0] – pdaPlayers[1] );
                //  Set the slots before returning
                pdaPlayers[0] = weak_race;
                pdaPlayers[1] = strong_race;
        }
}

(IBAction) btCalculate_Clicked:(id)sender
{
        NSLog( @“Button clicked start”);
       
        double dPlayerOne = [txPlayer1.text doubleValue];
        double dPlayerTwo = [txPlayer2.text doubleValue];

        // What is the race
        double players[2] = { dPlayerOne, dPlayerTwo };

        // call the function to calculate
        [ self calculate: players ];

        // Display it
        txWinPlayer1.text = [NSString stringWithFormat:@“%.0f”, players[0]];
        txWinPlayer2.text = [NSString stringWithFormat:@“%.0f”, players[1]];

        NSLog( @“Button clicked end”);
}

(void)dealloc
{
        // First half
        [lbPlayer1 release];
        [txPlayer1 release];
        [lbPlayer2 release];
        [txPlayer2 release];
       
        // Second half
        [lbWinPlayer1 release];
        [txWinPlayer1 release];
        [lbWinPlayer2 release];
        [txWinPlayer2 release];
   
        [super dealloc];
}

@end



I disabled the two result fields in code in the viewDidLoad function as it did not work to set Accessibility Enabled = false from the Interface builder, I don’t know why.
The textFieldShouldReturn function implements the functionality that goes with UITextFieldDelegate in the header file. Simply when the user is done with input in the two text fields he can hit return on the keyboard and the keyboard gets hidden again.
The calculate function is a straight port from the Android code, I only had to include tgmath.h and use the math functions from there.
The btCalculate_Clicked is where all the functionality happens, simply convert the text input from string to double then call calculate and display in the result fields. There is no error checking on the input as I was feeling lazy.
I’m using NSLog to log out to the console, if you want to create a program for production you should maybe write your own logging or use third party library to be able to control the logging level both debug and runtime.
Lastly we have dealloc function where we release the resources the code has been referencing. As pointed out by my friend Mick they are introducing automatic dellocations by the compiler called ARC ( Automatic Reference Counting ) in the near future. That should be welcomed by objective-c developers as they don’t have to keep track of and releasing resources, fewer bugs and more productivity. Some changes discussed on Stack Overflow This experience reminded me of other c / c++ coding with a twist I find the [ class function:param ] syntax strange, but I’m sure I can get used to that.


Below is the app in action and here is the code if anybody is interested HandiCap xCode project

2 Comments

  1. steve says:

    Sounds challenging to code for x on a PC. You’re a good code commenter 😉

    Thanks for sharing your experience.

  2. orn says:

    Just the keyboard layout, I should fix that on my VM. I wish they had the Linux keypad option on the Mac as well.

    ( Under Linux )
    Miscellaneous compatibility options
    Shift with numeric keypad keys works as in MS Windows (numpad:microsoft)

Leave a Reply