Wednesday, July 31, 2013

iOS For Beginners : Getting Started

This is a new tutorial series on beginning programming for iOS – for high school students, by high school students! We’ll walk you through creating an app from the very beginning, assuming zero knowledge! And we’ll make things tons of fun along the way. :]
You want to learn to develop iPhone apps, eh? Well, learning how to program is the first step.
In this tutorial, we’ll get started with the basics of programming in Objective-C and create a simple Mac app called “Are you a WIZARD?”
“Wait a minute,” you might say to yourself. “Why are we making a Mac app? I wanted to make an iOS app!” Well, making a command-line Mac app is a nice and easy way to experiment with the basics of programming before we get into more complex subjects.
To follow along with this tutorial, you’ll need a Mac (preferably one that is not super-old) and Xcode. You can download Xcode for free from the Mac App Store!

Getting Started

Click Setting Up Your Programming Environment for a visual guide to setting up Xcode. Otherwise, follow the instructions below. :]
Step One. Open Xcode and select the option to create a new Xcode project from the popup, or select File\New\New Project from the menu.
Step Two. Choose the Command Line tool by selecting Mac OS X>Application>Command Line Tool.
Step Three. Enter “Are You A WIZARD?” for the Product Name. Change the file type to: Foundation. Save the project somewhere you can easily find it!
Step Four. On the left side of the Xcode window is a simple file hierarchy. The file main.m is the only thing we are going to work on, so click it to open it. You should see the following code:
//
//  main.m
//  Are You A WIZARD?
//
#import 
 
int main (int argc, const char * argv[])
{
 
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
 
    // insert code here...
    NSLog(@"Hello, World!");
 
    [pool drain];
    return 0;
}
You’ve done it! You have created your first application! Excellent job! :p

Understanding The Hello World Application

As you may have figured out, your new project has a simple program pre-coded as a template. It is known universally as “Hello World!” and has been the traditional “first program” for beginning coders for decades!
Press the Run button in the upper lefthand corner. By clicking Run you are actually telling Xcode to build (compile all files into a single program) and run the program. You should see the following output in the lower part of the screen:
Hello, World!
Here’s a screenshot showing where you can find this (and I’ve circled the buttons you should click to bring up the console panel if it isn’t open already):
Hello World output in Xcode console
Now I’ll explain each line in the Hello World program. Armed with that knowledge, we will move straight to the “Are You A WIZARD?” game.
The first section of code, shown below, is not actually part of the program! It is completely ignored by the compiler.
//
//  main.m
//  Are You A WIZARD?
//
How does the compiler know to ignore these lines? The key is the double forward slash marks (“//”) at the beginning of each line. They tell the compiler, “Nothing to see here, move along.”
Programmers use // lines to document their work by writing comments into the code that do not affect the program. We will use some in a little bit.
The next statement, below, simply means “go grab Foundation/Foundation.h, because it has some stuff we need for the program.”
#import 
We could import any header file with the import command. However, Foundation.h (foundation.header file) is the one we need for our command line application.
The next section, called the main function, is the heart of the program. It is all contained within brackets {}.
At the beginning of every program you will have to import various files (such as Foundation.h), define methods, blah blah blah. However, after all of that infrastructure is brought together, the main {} is where you begin to execute each step.
int main (int argc, const char * argv[])
{
 
}
Still confused? Well I’ll try a super lame analogy to explain this, so bear with me. :/
Objective-C programming is like baking a cake!
Objective-C programming is like baking a cake! Image credit: planetka from sxc.hu
If you were going to bake a cake, you would first gather all the ingredients and tools you needed, right? You might get the eggs out along with the milk, pan, egg beater, etc.
Even if you didn’t put all these things on the counter right away, you would at least scan the list of ingredients to see what you needed!
Well, the ingredients and tools are like the header file (Foundation.h), and the recipe is like the main function, or everything within the main brackets. I hope that helps!
Now we will go through the main function line by line. Note:Everything within the brackets {} is called a block statement. Every statement within a block statement requires a semicolon “;” at the end.
The first line allows our program to use (borrow) memory from the computer for our application. Don’t worry if this is confusing, just think of it as something you need to add at the start of a program for now. All will be clear in the future. :]
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
Careful reader, you ought to know what this next line is: just a comment! As we discussed earlier, the “//” instructs the compiler to ignore the line.
// insert code here...
Next we have our first function, NSLog(). A function is a block of code that performs a specific task. It has a name and it is reusable.
NSLog(@"Hello, World!");
NSLog() is a function with a very simple task. It displays everything between the first and second double quotation marks, or as we say, it displays a string (a list of characters), which is exactly what the statement “Hello, World!” is.
Note the quotation marks has a little @ sign beforehand. You need to put this whenever you use a string in Objective-C. It’s easy to forget to add this, but if you do your program will crash, so be careful!
After NSLog, our program has completed its purpose. However, we have borrowed memory in an autorelease pool, and everything that required memory is now finished. So, the line below instructs the computer to drain the “pool” of memory so that the device can use the memory elsewhere.
[pool drain];
Always releasing memory at the end of a program is a good habit to have as an iOS developer! Although the applications we write will not be memory intensive on a Mac, iOS devices have very limited RAM. Every time we borrow memory from the device and forget to release it, that memory cannot be used for other important tasks.
Finally, the last piece of code! “Return 0″ terminates the main function by requiring the console to return the value 0, if everything was successful.
return 0;
Go ahead and click Run again. The final line of output should read “Program ended with exit code: 0.” If you get code: 0, then everything ran correctly.
Now let’s try something. Go ahead and substitute the value 3 for 0 in the last line of your main function (“return 3;”) and click Run again. You should understand that the command returns whatever you want to use to test that the program ran correctly.
Phew! Hopefully this coding business looks a little less intimidating now. But that code was provided for us, and all we had to do was press Run. NEXT, we begin creating our own application involving wizards and special powers!

Creating Our Own Application

The goal of the Are You A WIZARD? program is to tell you what class of person you are, based on your input. The program will ask questions that can be answered on a scale of 1-10.
But as the programmers, we will create the questions and responses that the computer will display! There is a lot of potential to make fun variations of this program for your friends to try. Let’s begin.
Starting with the template provided, let’s remove the NSLog function and the comment above it, since we don’t need them. We end up with this:
//
//  main.m
//  Are You A WIZARD?
//
#import 
 
int main (int argc, const char * argv[])
{
 
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
 
    [pool drain];
    return 0;
}
Go ahead and run it again to make sure it still compiles and runs (but of course it won’t print out the “Hello, World” anymore since you deleted it!).

Variables

Now we need to create some variables.
Variables are essential because they make it significantly easier to manipulate information. They allow us to use a symbolic name that is independent of the information it represents, very similar to how variables are used in mathematics.
There are four basic types of variables, and for each variable we create, we need to tell our “brainless” computer what type it is. :p Here’s a brief run-down:
  • int: stands for an integer variable; a whole number, a number that is not a fraction; examples: -2,-1,0,1,2
  • float: stands for a floating-point variable; any number that is expressed with a decimal; examples: 3.5, 3.0, -.001
  • double: stands for an extended floating-point variable; any number that exceeds the range of float; examples: 10000000000000000
  • char: stands for any character variable; examples: x, a, b, d, $, #
We create variables by making the following type of declaration:
int x; //this basically means we created an integer variable named "x"
float bee; //this is a float variable named "bee"
So let’s create some variables for our program. We will use our variables to determine whether or not someone is a wizard.
You can create your own variables if you want. However, I strongly recommend working through this tutorial with the variables I provide, so that you don’t inadvertently create any errors!! Change ‘em later, friends. :]
In the main function below, I’ve added the following variables: strength, intelligence, speed, alchemy_skill, sum, and avg. They are all float variables. Don’t worry for now what the variables mean.
//
//  main.m
//  Are You A WIZARD?
//
#import 
 
int main (int argc, const char * argv[])
{
 
     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
 
     //These are the different variables that will be evaluated to generate responses:
     float strength, intelligence, speed, alchemy_skill, sum, avg; 
 
     [pool drain];
     return 0;
}
Notice how I declared all the variables in a single line, separating them with commas. But you could also write them like so:
float strength;
float intelligence;
float speed;
float alchemy_skill;
float sum;
float avg;
Notice also how I inserted a comment into my code with the // marks. It makes understanding the code a little easier, either for your forgetful self, or for other people reading your code! Trust me, somebody (possibly you!) will be glad you did it.
It’s not enough to just create variables, though. We have to assign them values. But sit tight, we will shortly.

Printing Statements

Now let’s create the questions we want the computer to ask the user. Let’s start with the following questions:
  • What is your strength?
  • What is your intelligence?
  • What is your speed?
  • What is your alchemy skill level?
Now we want to tell the computer to print these statements. Each of these statements is just a bunch of characters crammed together right? So, we use the NSLog function, the same one used in the Hello World application. All it does is print a string of characters. The format is as follows:
NSLog(@"Whatever you want to say. :p");
Easy, right? We would implement it like this in our program to code the above questions:
//
//  main.m
//  Are You A WIZARD?
//
#import 
 
int main (int argc, const char * argv[])
{
 
     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
 
     //These are the different variables that will be evaluated to generate responses. 
     float strength, intelligence, speed, alchemy_skill, sum, avg;
 
     //I included (1-10) so that users would know how to answer.
     NSLog(@"What is your strength (1-10)?");
     NSLog(@"What is your intelligence (1-10)?");
     NSLog(@"What is your speed (1-10)?");
     NSLog(@"What is your alchemy skill level (1-10)?");
 
     [pool drain];
     return 0;
}
Now let’s run the program and see what we’ve got!
Did it work? Then that’s it, you’re done!
Just kidding, let’s keep working. :]

Using Scanf For Input and Assigning Variables

The next big thing is that we want the user to be able to interact with the program. As it is, the program just spits out questions.
Fortunately, we have a function that specifically takes input from the keyboard, scanf(). The scanf() function takes an input from the user of the program and it stores it as a variable. We call this input the “argument.” Below is the syntax of the scanf() function.
scanf("%f", &strength);
This tells the computer: “Wait for the user to input something (the argument). The argument must be a float (that’s what “%f” means). Store that input as the value of the variable ‘strength’ (which we already created).”
In other words, the scanf() function is one way of assigning values to variables!
Realize that “%f” and “&” are just part of the syntax you will need to memorize. Because we are storing the input in a float variable, we use “%f.” If our input was being stored in an integer variable we would use “%i” instead. Below are the various operators used with their respective variable types.
int%i
float%f
double%d
char%c
Since we want to get input after every question, that means we’re going to need to… use scanf() after each NSLog()! Give it a try and check your program with mine below.
//
//  main.m
//  Are You A WIZARD?
//
#import 
 
int main (int argc, const char * argv[])
{
 
     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
 
     //These are the different variables that will be evaluated to generate responses. 
     float strength, intelligence, speed, alchemy_skill, sum, avg;
 
     //I included (1-10) so that users would know how to answer
     NSLog(@"What is your strength (1-10)?");
     scanf("%f", &strength);
 
     NSLog(@"What is your intelligence (1-10)?");
     scanf("%f", &intelligence);
 
     NSLog(@"What is your speed (1-10)?");
     scanf("%f", &speed);
 
     NSLog(@"What is your alchemy skill level (1-10)?");
     scanf("%f", &alchemy_skill);
 
     [pool drain];
     return 0;
}
So far, this program tells the computer the user’s strength, intelligence, speed, and alchemy skill. Those variables get assigned a value according to what the user types as input. However, we have some variables that were not assigned a value.
Remember, we created two additional variables:
float sum;
float avg;
We’re going to have our program compute sum and avg as combinations of the other four variables, which is why we didn’t use scanf() to assign them. We will define sum and avg as follows:
sum = strength + intelligence + speed + alchemy_skill;
avg = (strength + intelligence + speed + alchemy_skill)/4;
Important point: because sum and avg are being assigned values that are combinations of other variables, these other variables must be assigned a value first. So the two lines above must go after the last scanf() function. Your program should look like this:
//
//  main.m
//  Are You A WIZARD?
//
#import 
 
int main (int argc, const char * argv[])
{
 
     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
 
     //These are the different variables that will be evaluated to generate responses. 
     float strength, intelligence, speed, alchemy_skill, sum, avg;
 
     //I included (1-10) so that users would know how to answer
     NSLog(@"What is your strength (1-10)?");
     scanf("%f", &strength);
 
     NSLog(@"What is your intelligence (1-10)?");
     scanf("%f", &intelligence);
 
     NSLog(@"What is your speed (1-10)?");
     scanf("%f", &speed);
 
     NSLog(@"What is your alchemy skill level (1-10)?");
     scanf("%f", &alchemy_skill);
 
     sum = strength + intelligence + speed + alchemy_skill;
     avg = (strength + intelligence + speed + alchemy_skill)/4;
 
    [pool drain];
    return 0;
}

Programming with Logic: If Statements

The next step requires the computer to print a message based on the skill set of the user. This requires us to write some logic code. In plain English, we want to tell the computer to do the following, for example:
  • If speed and intelligence are both really high, then print the message, “You are an assassin.”
  • If strength is really high, then print the message, “You are a troll.”
Let’s take this a step further and create a better example that uses numbers to define what is “really high”:
  • If strength is greater than or equal to 7, and intelligence is greater than or equal to 7, and the average of the user’s alchemy skill and speed is less than 7, then print: “You are a clever brute. You are known for your defense of Aristotle’s logic, while being equally admired by competent athletes. In the gladiator ring, your intelligence outmatches beings of even greater strength.”
Below is the snippet of code that executes the above paragraph. It uses something called an if-then statement. See if it makes sense. It’s something new, but you should be able to make some connections. :]
if (strength >= 7 && intelligence >= 7 && (alchemy_skill + speed)/2 < 7)
     {
     NSLog(@"You are a clever brute. You are known for your defense of Aristotle's logic, while being equally admired by competent athletes. In the gladiator ring, your intelligence outmatches beings of even greater strength.")
     }
In case you’re confused, a few things to keep in mind. The “if” conditions are all within the first set of parentheses (). The twin ampersands (“&&”) simply mean “and.” Every condition linked by && has to be met to trigger the “then” statements, which follow in the brackets {}.
We are going to take this (and a bunch of other if-then statements) and paste them into our program after the declarations of our sum and avg variables.
//
//  main.m
//  Are You A WIZARD?
//
#import 
 
int main (int argc, const char * argv[])
{
 
     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
 
     //These are the different variables that will be evaluated to generate responses. 
     float strength, intelligence, speed, alchemy_skill, sum, avg;
 
     //I included (1-10) so that users would know how to answer
     NSLog (@"What is your strength (1-10)?");
     scanf ("%f", &strength);
 
     NSLog (@"What is your intelligence (1-10)?");
     scanf ("%f", &intelligence);
 
     NSLog (@"What is your speed (1-10)?");
     scanf ("%f", &speed);
 
     NSLog (@"What is your alchemy skill level (1-10)?");
     scanf ("%f", &alchemy_skill);
 
     sum = strength + intelligence + speed + alchemy_skill;
     avg = (strength + intelligence + speed + alchemy_skill)/4; 
 
     //Here are the logical statements that determine a response based on the user's input for various skills!
     if (strength >= 8 && intelligence >= 8 && (alchemy_skill + speed)/2 < 7)
     {
     NSLog(@"You are a clever brute. You are known for your defense of Aristotle's logic, while being equally admired by competent athletes. In the gladiator ring, your intelligence outmatches beings of even greater strength.");
     }
     if (speed >= 8 && intelligence >= 8 && (alchemy_skill + strength)/2 < 7) 
     {
     NSLog(@"You are an assassin. Your sharp blade and agile mind gleam in the shadows. Being not particularly confrontational, you wear an aura of mystery.");
     }
     if (alchemy_skill >= 8 && intelligence >= 8 && (strength + speed)/2 < 7)
     {
     NSLog(@"You are a cleric. You summon mysterious powers to heal and protect.");
     }
     if (avg >= 8 && avg <= 9)
     {
     NSLog(@"You are a mage, apprenticed to a great wizard. One day you may be a master of the universe.");
     }
     if (avg >= 5 && avg <= 7)  
     {
     NSLog(@"You are a commoner. You will live a long life, and tend to your property.");
     }
     if (avg >= 1 && avg <= 4) 
     {
     NSLog(@"You are a peasant. Your lord is cruel. He does not compensate you for the work that you accomplish. You only dream of being successful. :(");
     }
     [pool drain];
     return 0;
}

Solving Problematic Inputs with While Loops and Else Statements

Well, our program is pretty cool, but there are a few setbacks preventing it from being a killer program. Run the program a few times, and each time use one of the below sets of input:
  • (12, 14, 56, 2)
  • (8, 8, 4, 4)
  • (10, 10, 10, 10)
Let’s first discuss the following problematic inputs (12, 14, 56, 2). Here’s what our current program does with these inputs:
Although in the print statements we declared that answers ought to range from (1-10), the reality is that the user can input whatever they want. If they input answers outside of the range (1-10), the program ceases to function. :O
As the rage comic indicates, we need something called a while loop to overcome those inclined to rebellious behavior. The idea behind the while loop is this:
While people answer values we don’t want, tell them they’re stupid, and make them answer the question again. (Just kidding :p)
While strength is greater than 10 or strength is less than 1, then print: “Your answer is deceitful! What is your strength?” Next, use scanf() to allow them to retry their input. This should make sense when you read the code below.
while(strength>10||strength<1) 
     {
     NSLog(@"Your answer is deceitful!");
     NSLog(@"What is your strength (1-10)?");
     scanf("%f", &strength);
     }
Note that || means “or.”
You might be asking what is the difference between a while statement (often called a while loop) and an if-then statement.
if(strength>10||strength<1) 
     {
     NSLog(@"Your answer is deceitful!");
     NSLog(@"What is your strength (1-10)?");
     scanf("%f", &strength);
     }
An if statement runs once. After the completion of its conditions (strength>10 or strength<1 and="" concludes.="" it="" its="" p="" runs="" statements="">
If we code the program with the if statement, answer 57 the first time we are asked to input our strength and 64 the second time, we get the following output:
Notice that the if statement ends and stores 64 as a legitimate value of strength. :(
We simply need to add a while loop for every variable that needs an input of value 1-10. Write out the while loops, then check your code with what is below. Run the program and test entering input outside of the range of (1-10). The while loop prevents the user from advancing until conditions are met.
//
//  main.m
//  Are You A WIZARD?
//
 
#import 
 
int main (int argc, const char * argv[])
{
 
     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
 
     //These are the different variables that will be evaluated to generate responses.
     float strength, intelligence, speed, alchemy_skill, sum, avg; 
 
     NSLog(@"What is your strength (1-10)?");
     scanf("%f", &strength);
 
     //Each while statement is designed to make sure that inputs for each question are between 1 and 10
     while(strength>10||strength<1) 
          {
          NSLog(@"Your answer is deceitful!");
          NSLog(@"What is your strength (1-10)?");
          scanf("%f", &strength);
          }
 
     NSLog(@"What is your intelligence (1-10)?");
     scanf("%f", &intelligence);
 
     //Each while statement is designed to make sure that inputs for each question are between 1 and 10
     while(intelligence>10||intelligence<1) 
          {
          NSLog(@"Your answer is deceitful!");
          NSLog(@"What is your intelligence (1-10)?");
          scanf("%f", &intelligence);
          }
 
     NSLog (@"What is your speed (1-10)?");
     scanf ("%f", &speed);
 
     //Each while statement is designed to make sure that inputs for each question are between 1 and 10
     while(speed>10||speed<1) 
          {
          NSLog(@"Your answer is deceitful!");
          NSLog(@"What is your speed (1-10)?");
          scanf("%f", &speed);
          }
 
     NSLog (@"What is your alchemy skill level (1-10)?");
     scanf ("%f", &alchemy_skill);
 
     //Each while statement is designed to make sure that inputs for each question are between 1 and 10
     while(alchemy_skill>10||alchemy_skill<1) 
          {
          NSLog(@"Your answer is deceitful!");
          NSLog(@"What is your alchemy_skill (1-10)?");
          scanf("%f", &alchemy_skill);
          }
 
     sum = strength + intelligence + speed + alchemy_skill;
     avg = (strength + intelligence + speed + alchemy_skill)/4; 
 
     //Here are the logical statements that determine a response based on the user's input for various skills!
     [...]
Our program is significantly more sound because of the while loops.
All right, let’s move on to the next problematic output, (8, 8, 4, 4). (We are almost to the coolest part of the program!) Here’s what we get:
For a single set of input, we get two outputs. :( This means that some of the conditions for our if statements are overlapping. The input (8, 8, 4, 4), in that order, means the user is a clever brute. However, it just so happens that the average of (8, 8, 4, 4) also generates the response: You are a commoner.
There are several other inputs that also generate two responses. But we don’t have to test every possible input with each if statement. We just have to use something called an else statement. Let me explain how they work in simple terms.
  • if (trees are green)
  • then (teach kids that trees are green)
  • else (teach kids that trees have something covering them)
We can also use an else-if statement. A clever brute could make sense of the code below. Can you? :]
  • if (trees are green)
  • then (teach kids that trees are green)
  • else if (trees are white)
  • then (teach teach kids that trees have snow on them)
When I designed the program, knowing that sometimes two answers would be generated, I decided to use a bunch of else-if statements. Use the image below to understand how else-if statements and else statements work.
In the series of if statements in the picture, the arguments only go out the horizontal tubes if they pass the condition. Once they pass the condition they are no longer considered. Immediately after the first statement, x is taken out of the running.
Else statements and else-if statements can only follow after an if statement. At the beginning of every new if statement, all variables are considered again.
If, else, and else-if statements are incredibly important. All you have to do now is look the if statements that should already be in your code. Keep the first one as an if statement and make each of the ones following an else-if statement. Look below for reference. All you are doing is creating the vertical tube illustrated in the picture. :)
 
     if (strength >= 8 && intelligence >= 8 && (alchemy_skill + speed)/2 < 7) 
     {
     NSLog(@"You are a clever brute. You are known for your defense of Aristotle's logic, while being equally admired by competent athletes. In the gladiator ring, your intelligence outmatches beings of even greater strength.");
     }
     else if (speed >= 8 && intelligence >= 8 && (alchemy_skill + strength)/2 < 7) 
     {
     NSLog(@"You are an assassin. Your sharp blade and agile mind, gleam in the shadows. Being not particularly confrontational, you wear an aura of mystery.");
     }
     else if (alchemy_skill >= 8 && intelligence >= 8 && (strength + speed)/2 < 7)
     {
     NSLog(@"You are a cleric. You summon mysterious powers to heal and protect.");
     }
     else if (avg >= 8 && avg <= 9)
     {
     NSLog(@"You are a mage, apprenticed to a great wizard. One day you may be a master of the universe.");
     }
     else if (avg >= 5 && avg <= 7)  
     {
     NSLog(@"You are a commoner. You will live a long life, and tend to your property.");
     }
     else if (avg >= 1 && avg <= 4) 
     {
     NSLog(@"You are a peasant. Your lord is cruel. He does not compensate you for the work that you accomplish. You only dream of being successful. :(");
     }
Now when you input (8, 8, 4, 4), you only get one output. :D

The Infinite While Loop

The final and most important part to the “Are You A WIZARD?” program is about to be revealed. Up until now there has been no possibility for a user to generate a wizard class, so we must create an output for one who possesses the greatest traits. Right now an input of (10, 10, 10, 10) results in the following output (or lack thereof):
In order to change this, we are going to create an infinite loop (for fun)! This is where we use the sum variable. (Wondering what had happened to that, huh?)
While we use the operator “=” to assign a value to a variable, the double “==” means “equal to,” a key distinction. The only time that the sum of all four skills can equal 40 is if they are each 10. Paste this on the line before your first if statement. Make sure you understand what this is saying.
 while (sum == 40) 
 {
 NSLog(@"You are a WIZARD! You cannot be defeated!! This simple program loops in honor of you!");
 }
A while statement will execute the command until the condition is no longer met. This statement reads “while the sum equals 40, print the NSLog statement.” Run the program, and see if you qualify as a wizard. :p