Getting Started
The first thing you need to do is install a free program called Xcode. Xcode is Apple’s Integrated Development Environment, or IDE, which is the main tool you’ll use to create your OS X and iOS apps. Download and install it from the App Store via this link.
Your first project in Xcode will be a small Mac OS X command-line app.
“Wait a minute,” you may think, “Why am I creating a Mac OSX command line app, I wanted to make an iPhone app!”
Well, both Native Mac and iOS apps are both written in the same programming language — Objective-C — and use the same set of tools to create and build applications. So starting with a command line app is the simplest way to start learning the basics. Once you’ve mastered doing some basic things there, making an iPhone app (like you’ll do later in this series) will be that much easier!
So let’s get started. Open up Xcode, and you’ll see a window that looks like this:
Click the button that says Create a new Xcode project, located directly below the Welcome to Xcode title, as shown in the screenshot below:
If you accidentally close the “Welcome to Xcode” window, you can create a new project by going to the Filemenu and selecting New > Project….
In the column on the left hand side, find the OS X section, click on Application and select Command Line Toolas shown below:
Click Next. On the following screen, fill in the fields as indicated:
- Product Name: My First Project
- Organization Name: This field can be left blank. Or you can enter your company name.
- Company Identifier: Enter com.yourname, such as com.johnsmith
- Type: Foundation
- Use Automatic Reference Counting: Check this box
Your screen should resemble the one below:
Click Next. Choose a location to store the project files (the Desktop is as good a place as any), and click Create. Xcode will set up your new project and open it up in the editor for you.
Running Your First App
Xcode comes with project templates which include some basic starter code; that means that even before you’ve written a line of code, you can run your project and see what it looks like. Granted, your project won’t do much right now, but this is a good opportunity to become familiar with running your project and viewing the output.
To build and run your project, find the Run button on the upper left corner of the Xcode window, as shown below, and click it:
Look at the bottom of the screen in the All Output pane; you should see Hello, World! displayed there, as shown below:
How about that — you’ve created and run your first OS X program! Before you go adding more functionality to your program, take a few minutes and got through the following sections to learn about the various parts of Xcode and how your program is structured.
Note: If you want to learn more about Xcode and how to use it, you can always refer to the Apple Xcode User Guide.
The left pane of Xcode displays a list of files that are part of the project. The files you see were automatically created by the project template you used. Find main.m inside the My First Project folder and click on it to open it up in the editor, as shown below:
The editor window should look very similar to the following screenshot:
Find the following line located around the middle of the file:
NSLog(@"Hello, World!"); |
Aha — this looks like the line that printed out the text that you saw in the “All Output” pane. To be certain of that, change the text to something else. Modify the line as shown below:
NSLog(@"I can write anything I want!"); |
Click the Run button; you should see your new text in the “All Output” pane as shown below:
You have now changed your program to output your own custom message. But there’s obviously more to the app than just a single line of output. What makes the app tick?
The Structure of Your Source Code
main.m is the source code of your application. Source code is like a list of instructions to tell the computer what you want it to do.
However, a computer cannot run source code directly. Computers only understand a language called machine code, so there needs to be an intermediate step to transform your high-level source code into instructions that the CPU can carry out. Xcode does this when it builds and runs your app by compiling your source code. This step processes the source code and generates the corresponding machine code.
If this sounds complicated, don’t worry — you don’t need to know anything about the machine language part other than to know it’s there. Both you and the compiler understand Objective-C code, so that’s the common language you’ll use to communicate.
At the top of main.m, you’ll see several lines beginning with two slashes (
//
), as shown in the screenshot below:// // main.m // My First Project // // Created by You on 4/18/13. // Copyright (c) 2013 You. All rights reserved. // |
These lines are comments and will be ignored by the compiler. Comments are used to document the code of your app and leave any tidbits of information that other programmers — or your future self — might find useful. Look at the middle of the file and you will see a perfect example of this:
// insert code here... NSLog(@"I can write anything I want!"); |
The comment
// insert code here...
is part of the project template from Xcode. It doesn’t change how the program runs, but it was put there by some helpful engineer at Apple to help you understand the code and get started.Import Statements
Directly below the comments at the top of main.m is the following line:
#import <Foundation/Foundation.h>
|
That line of code is known as an import statement. In Xcode, not everything has to be contained in one single file; instead, you can use code contained in separate files. The import statement tells the compiler that “when you compile this app, also use the code from this particular file”.
As you can imagine, developing for OS X and iOS requires a lot of diverse functionality, ranging from dealing with text, to making requests over a network, to finding your location on a map. Rather than include a veritable “kitchen sink” of functionality into every app you create, import statements allow you to pick which features you require for your app to function. This helps to decrease the size of your code, the processing overhead required, and compile time.
Apple bundles OS features into frameworks. The import statement shown above instructs the compiler to use the Foundation framework, which provides the minimum foundation (as the name suggests) for any app.
Here’s a bit of trivia for you: how many lines of code do you think Foundation/Foundation.h adds to your main.m file? 10? 1000? 100000? A million?
Solution Inside: Foundation.h lines of code | Show |
---|---|
The Main Function
Look at the line following the
import
statement:int main(int argc, const char * argv[]) |
This line declares a function called
main
. All of the code in your app that provides some type of processing or logic is encapsulated into functions; the main
function is what kicks off the whole app.
Think of a function as a unit of code that accepts input and produces output. For example, a function could take an account number, look it up in a database, and return the account holder’s name.
The
int
part of int main
means the return value of main
returns an integer such as 10 or -2. The (int argc, const char * argv[])
bits in parentheses are the arguments, or inputs, to the function. You’ll revisit the arguments of a function a bit later on.
Immediately below
int main
is an open curly brace ({
) which indicates the start of the function. A few lines down you’ll see the corresponding closing curly brace (}
). Everything contained between the two braces is part of themain
function.
Since Objective-C is a procedural language, your program will start at the top of
main
and execute each line of the function in order. The first line of main
reads as follows:@autoreleasepool {
|
Just like in
main
, curly braces are used to surround a group of related lines of code. In this case, everything between the braces are part of a common autorelease pool.
Autorelease pools are used to manage memory. Every object you use in an app will consume some amount of memory — everything from buttons, to text fields, to advanced in-memory storage of user data eats away at the available memory. Manual memory management is a tricky task, and you’ll find memory leaks in lots of code — even code written by expert programmers!
Instead of tracking all the objects that consume memory and freeing them when you’re done with them,
autoreleasepool
automates this task for you. Remember when you created your project in Xcode and checked “Use Automatic Reference Counting”? Automatic Reference Counting, or ARC, is another tool that helps manage memory in your app so you almost never need to worry about memory usage yourself.
You’ll recognize the next line; it’s the one that you edited to create a custom message:
NSLog(@"I can write anything I want!"); |
The
NSLog
function prints out text to the console, which can be pretty handy when you’re debugging your code. Since you can’t always tell exactly what your app is doing behind the scenes, NSLog
statements help you log the actions of your app by printing out things like strings or the values of variables. By analyzing the NSLog
output, you’ll gain some insight as to what your app is doing.
If you’re worried about your end user seeing
NSLog
statements on their iPhones, don’t fret — the end user won’t see the NSLog
output anywhere in the app itself.
In programming, text inside double quotation marks is known as a string. A string is how you store words or phrases. In Objective-C, strings are prefixed with an
@
sign.
Look at the end of the
NSLog
line, you’ll see that the line is terminated by a semicolon. What does that do?
The Objective-C compiler doesn’t use line breaks to decide when one “line” of code ends and when one begins; instead, semicolons indicate the end of a single line of code. The
NSLog
statement above could be written like this:NSLog( @"I can write anything I want!" ) ; |
…and it would function in the same manner.
To see what happens when you don’t terminate a line of code with a semicolon, delete the semicolon at the end of the
NSLog
statement, then press the Run button. You’ll see the following error indicated in Xcode:
The
NSLog
line is highlighted in red, and a message states "Expected ';' after expression"
. Syntax errors like this stop the compiler in its tracks, and the compiler won’t be able to continue until you fix the issue. In this case, the correction is simple: just add the semicolon at the end of the line, and your program will compile and run properly.
There’s just one more line of code to look at in
main
:return 0; |
This line of code is known as a return statement. The function terminates when this line is encountered; therefore any lines of code following the return statement will not execute. Since this is the main function, this
return
statement will terminate the entire program.
What does the “0” mean after the
return
statement? Recall that this function was declared as int main
, which means the return value has to be an integer. You’re making good on that promise by returning the integer value “0”. If there are no actual values to be returned to the caller of this function, zero is typically used as the standard return value for a function to indicate that it completed without error.Working With Variables
Computers are terribly good at remembering pieces of information such as names, dates, and photos. Variablesprovide ways for you to store and manipulate these types of objects in your program. There are four basic types of variables:
- int: stores a whole number, such as 1, 487, or -54.
- float: stores a floating-point number with decimal precision, such as 0.5, 3.14, or 1.0
- char: stores a single character, such as “e”, “A”, or “$”.
- BOOL stores a YES or NO value, also known as a “boolean” value. Other programming languages sometimes use TRUE and FALSE.
To create a variable — also known as declaring a variable — you simply specify its type, give it a name and optionally provide a default value.
Add the following line of code to main.m between the
@autoreleasepool
line and the NSLog
line:int num = 400; |
Don’t forget that all-important semicolon!
The line above creates a new integer variable called num and assigns it a value of 400.
Now that you have a variable to use in your app, test it out with an
NSLog
statement. Printing out the values of variables is a little more complicated than printing out strings; you can’t just put the word “num” in the message passed to NSLog
and see it output to the console.
Instead, you need to use a construct called format specifiers which use placeholders in the text string to show
NSLog
where to put the value of the variable.
Find the following line in main.m:
NSLog(@"I can write anything I want!"); |
…and replace it with the following line of code:
NSLog(@"num equals %i", num); |
Click the Run button in the upper left corner. You should get a message in the console that says:
num equals 400
|
That looks great — but how did Xcode know how to print out the value of
num
?
The
%i
in the code above is a format specifier that says to Xcode “replace this placeholder with the first variable argument following this quoted string, and format it as an integer”.
What if you had two values to print out? In that case, the code would look similar to the following:
NSLog(@"The two variables are %i and %i", num1, num2); |
Okay, so
%i
is used for integer formatting. But what about other variable types? The most common format specifiers are listed below:- %i: int
- %f: float
- %c: char
There isn’t a specific format specifier for boolean values. If you need to display a boolean value, use
%i
; it will print out “1” for YES and “0” for NO.
Along with declaring variables and setting and printing values, you can also perform mathematical operations directly in your code.
Add the following line to main.m, immediately below the
int num = 400;
line:num = num + 100; |
The above code takes the current value of
num
, adds 100 to it, and then replaces the original value of num
with the new sum — 500.
Press the Run button in the upper left corner; you should see the following output in your console:
num equals 500
|
That’s enough theory to get started — you’re probably itching to start coding your first real app!
Building Your First Game
The application you’ll create in this tutorial is the classic game “Higher or Lower”. The computer generates a secret random number and prompts you to guess what that number is. After each successive guess, the computer tells you if your guess was too high or too low. The game also keeps track of how many turns it took for you to guess the correct number.
To get started, clear out all of the lines in the
@autoreleasepool
block of main.m so that main
looks like the code below:int main(int argc, const char * argv[]) { @autoreleasepool { } return 0; } |
All the code you add in the steps below will be contained between the curly braces of the the
@autoreleasepool
block.
You’re going to need three variables: one to store the correct answer, one to store the player’s guess and one to store the number of turns.
Add the following code within the
@autoreleasepool
block:int answer = 0; int guess = 0; int turn = 0; |
The code above declares and initializes the three variables you need for your game. However, it won’t be much fun to play the game if
answer
is always zero. You’ll need something to create random numbers.
Fortunately, there’s a built-in random number generator,
arc4random
, which generates random numbers for you. Neat!
Add the following code directly below the three variable declarations you added earlier:
answer = arc4random(); NSLog(@"The random value is %i", answer); |
answer
now stores a random integer. The NSLog
line is there to help you test your app as you go along.
Click the Run button in the upper left corner and check your console output. Run your app repeatedly to see that it generates a different number each time. It seems to work well, but what do you notice about the numbers themselves?
The numbers have a huge range — trying to guess a number between 1 and 1228691167 doesn’t sound like a lot of fun. You’ll need to scale those numbers back a little to generate numbers between 1 and 100.
There’s an arithmetic operator called the modulo operator — written as
%
in Objective-C — that can help you with this scaling. The modulo operation simply divides the first number by the second number and returns the remainder. For example, 14705 % 100
will produce 5
, as 100 goes into 14705 a total of 147 times, with a remainder of 5.
To scale your values back between 1 and 100, you can simply use the above trick on your randomly generated numbers. However, if you divide the randomly generated number by 100, you’ll end up with numbers that range from 0 to 99. So, you simply need to add 1 to the remainder to get values that range from 1 to 100.
Find the following line in your code:
answer = arc4random(); |
…and modify it to look like the line below:
answer = arc4random() % 100 + 1; |
Run your app a few times and check the console output. Instead of huge numbers, your app should only produce numbers between 1 and 100.
You now know how to create and display information to your user, but how do you go about accepting input from the user to use in your app?
That’s accomplished by the
scanf
function — read on to learn how it works.Obtaining User Input
Add the following lines of code immediately after the previously added code:
NSLog(@"Enter a number between 1 and 100"); scanf("%i", &guess); NSLog(@"You entered: %i", guess); |
Aha — that
%i
looks familiar, doesn’t it? Format specifiers are used for output and input functions in your app. The %i
format specifier causes scanf
to process the player’s input as an integer.
Run your app; when you see the “Enter a number” prompt, click your mouse in the console to make the cursor appear. Type a number and press Enter; the program should print the number back to you, as shown in the screenshot below:
Now that you’ve confirmed that the random number generator and the user input methods work, you don’t need your debug statements any longer. Remove the following two
NSLog
statements from your code:NSLog(@"The random value is %i", answer); |
and
NSLog(@"You entered: %i", guess); |
Okay — you have the basic user input and output methods in place. Time to add some game logic.
Working With Conditionals
Right now, your code runs from top to bottom in a linear fashion. But how do you handle the situation where you need to perform different actions based on the user’s input?
Think about the design of your game for a moment. Your game has three possible conditions that need to be checked, and a set of corresponding actions:
- The guess is too high — tell the player to guess a lower number
- The guess is too low — tell the player to guess a higher number
- The guess is correct — congratulate the player
Conditional statements are programming structures that allow you to make on-the-fly decisions in your code and change the flow of the logic. Conditionals work by determining if a particular set of conditions is true. If so, then the app will perform the corresponding specific set of actions.
Add the following lines of code immediately after the
scanf("%i", &guess);
line:if (guess > answer) { NSLog(@"Lower!"); } else if (guess < answer) { NSLog(@"Higher!"); } else { NSLog(@"Correct! The answer was %i", answer); } |
The conditional statement above starts with an
if
statement and provides a set of conditions inside the parentheses. In the first block, the condition is “is guess
greater than answer
?”. If that condition is true, then the app executes the actions inside the first set of curly braces, skips the rest of the conditional statement, and carries on.
If the first condition was not met, the reverse condition is tested with an
else if
statement: “is guess
less thananswer
?”. If so, then the app executes the second set of actions inside the curly braces.
Finally, if neither of the first two conditions are true, then the player must have guessed the correct number. In this case, the app executes the third and final set of actions inside the curly braces. Note that this
else
statement doesn’t have any conditions to check; this acts as a “catch-all” condition that will execute if none of the preceding conditions were true.
There are many different comparison operators that you can use in your
if
statements, including the ones listed below:- > : greater than
- < : less than
- >= : greater than or equal to
- <= : less than or equal to
- == : equal to
- != : not equal to
Note: To check if two variables are equal, use two equal signs. A single equals sign is the assignment operator, which assigns a value to a variable. It’s an easy mistake to make, but just remember that “equal TO” needs “TWO equals”! :]
Run your app, and try to guess the number that the computer chose. What happens after you make one guess?
Right now you can only enter one guess before the program quits. Unless you are extremely good at guessing — or psychic! :] — your app will tell you that your guess is incorrect and terminate.
Well, that’s no fun. You need some way to loop back to some point in the the program and give the player another chance to guess. Additionally, you want the app to stop when the player guesses the correct number.
This is a job for a while loop.
Working With While Loops
A while loop is constructed much like an
if
statement; they both have a condition and a set of curly braces that contain code to execute if the condition is true.
An
if
statement runs a code block only once, but a while loop will run the block of code repeatedly until the condition is no longer true. That means your code block needs an exit condition that makes the condition false to end the execution of the while loop. If you don’t have an exit condition, the loop could run forever!
The first question is which code needs to be inside the while loop. You don’t want to loop over the random number generation with the
arc4random
statement, or else the player will be guessing a new random number each time! Just the user prompt, scanf, and the conditional if
block needs to be looped over.
The other question is how to create your exit condition. The repeat condition is to loop while
guess
does not match answer
. This way, as soon as the user guesses the correct number, the exit condition occurs automatically.
Note that you will need to add two lines to your existing code to wrap your game logic in a while loop: the
while
statement itself, and the closing curly brace to close off the while
loop.
Modify your code to include the two lines indicated by the comments below:
while (guess != answer) { // first line to add NSLog(@"Enter a number between 1 and 100"); scanf("%i", &guess); if(guess > answer){ NSLog(@"Lower!"); } else if(guess < answer){ NSLog(@"Higher!"); } else{ NSLog(@"Correct! The answer was %i", answer); } } // second line to add — end of while loop |
Run your app, and play through the game a few times. How good of a guesser are you?
Adding the Final Touches
You now have a functional game! There’s only one thing to add: the turn counter. This will give your player some feedback on their gameplay.
The
turn
variable has already been created to store this information, so it’s just a matter of incrementing the value of turn
each time the player makes a guess.
Add the following line of code directly underneath the
while (guess != answer) {
statement:turn++;
|
turn++;
increments the count by one. Why don’t you just use turn = turn + 1;
, you ask? Functionally, it’s the same thing. However, incrementing a variable is such a common programming task that it pays to have a shorthand method to save on typing.
Fun Fact: The “C” programming language was derived from a previous language called “B”. When the next iteration of the C language was written, the developers put their tongue firmly in cheek and named the new language “C++” — meaning “one better than C”. :]
All that’s left to do is display the current value of
turn
in two places: on the user prompt, and at the end of the game.
Find the following line of code:
NSLog(@"Enter a number between 1 and 100"); |
…and modify it to look like the line below:
NSLog(@"Guess #%i: Enter a number between 1 and 100", turn); |
The code above uses the format specifier
%i
to display the current value of turn
in the user prompt.
Add the following line of code immediately after the closing curly brace of the while loop:
NSLog(@"It took you %i tries", turn); |
This will display the final number of guesses once the player has guessed the correct number.
If you feel adventurous, instead of adding the above line to log the number of turns after the while loop, you could also modify the congratulatory message to output the number of turns right there. But I’ll leave that as an exercise for you :]
Take a minute and review the contents of
main
in your app to make sure that it matches the code below:int main(int argc, const char * argv[]) { @autoreleasepool { int answer = 0; int guess = 0; int turn = 0; answer = arc4random() % 100 + 1; while (guess != answer) { turn++; NSLog(@"Guess #%i: Enter a number between 1 and 100", turn); scanf("%i", &guess); if (guess > answer) { NSLog(@"Lower!"); } else if (guess < answer) { NSLog(@"Higher!"); } else { NSLog(@"Correct! The answer was %i", answer); } } // end of while loop NSLog(@"It took you %i tries", turn); } return 0; } |
Run your app and check out the latest changes!
Where To Go From Here?
By creating this small app, you’ve learned some of the most fundamental concepts in Objective-C, namely:
- functions
if
..else
blocks- format specifiers
- while loops
The final project with full source code can be found here.
You’re now ready to move on to the next tutorial in this series, where you’ll learn about some more fundamental concepts in Objective-C, including working with objects and classes.
If you have any question or comments, come join the discussion on this series in the forums!
0 comments:
Post a Comment