Learn to Code iOS Apps 2: Strings, Arrays, Objects and Classes

Part 2 of a series where you’ll learn to code iOS apps using Apple’s development tools. For complete beginners – no prior programming experience needed! By Mike Jaoudi.

Leave a rating/review
Save for later
Share
You are currently viewing page 2 of 4 of this article. Click here to view the first page.

C-Strings vs. NSString

You might be wondering why you had to convert the contents of cstring to an NSString. A simple list of characters is known as a “C string”. In the C language, which is the predecessor to Objective-C, the only way to store characters is by sticking them in a list. It’s efficient — but a little unwieldy when you want to manipulate that string data.

NSString also stores a C string, but also provides a host of methods that allow you to do things such as get the string’s length and compare it to other strings.

Find the following line in your code:

NSLog(@"You entered the word '%@'", inputString);

…and change it to read as follows:

NSLog(@"You entered the word '%@' and it is %li characters long", inputString, [inputString length]);

Because inputString is an object, it can receive messages such as length, which causes it to report back the length of the string.

Run your app and enter a word. Your console session should look something like the following:

Please enter a word.
objects
You entered the word 'objects' and it is 7 characters long

Declaring an object like NSString is significantly different from declaring a simple primitive variable type. Here is how inputString is declared:

NSString *inputString = [NSString stringWithCString:cstring encoding:1];

NSString *inputString simply creates an NSString object named inputString. The asterisk (*) that precedes the name of the object turns the variable into a pointer. A pointer just stores the memory location of the object — not the object itself. When declaring objects, they are always declared as pointers using the asterisk notation.

Note: Declaring an object pointer does not automatically create the object, which is different from primitive type variables. If you look at the code example above, everything to the right of the equals sign is what creates the object. If you don’t actually create the object that the pointer references, the pointer will literally point to nothing.

Note: Declaring an object pointer does not automatically create the object, which is different from primitive type variables. If you look at the code example above, everything to the right of the equals sign is what creates the object. If you don’t actually create the object that the pointer references, the pointer will literally point to nothing.

Why are pointers necessary? Objects can take up a lot of memory; it’s more efficient and convenient to pass around the memory address to where the object is stored. Otherwise you would be making huge in-memory copies of the object for everyone to use.

The need for pointers when working with objects goes a little deeper, but for now just remember that you always refer to objects through pointers.

Working with Classes and Objects

Your next task will be to create a simple database that keeps track of names and ages by using objects and custom classes.

To start, clear out everything in the @autoreleasepool code block. The code in main.m should look like the following:

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[])
{
    @autoreleasepool {

    }
    return 0;
}

Think for a moment about how you will store each person’s record. It needs to contain their first name, their last name, and their age. Three pieces of data, all stored together — it sounds like a great use for an object, doesn’t it?

But there’s no predefined “Person” class in Objective-C. However, you can create your very own custom objects by defining a new class. A class is essentially a blueprint to say how an object should look and behave.

First, you’ll need to create a new file to hold your new class. In Xcode, navigate to File\New\File…, as shown below:

FileMenu

In the left column under OS X, select Cocoa. Then select Objective-C Class and click Next.

ObjectiveCClass

Set the class name to Person and the Subclass to NSObject. Click the Next button and then click Create, as illustrated below:

NamePerson

In the file navigator on the left, you should see two new files: Person.h and Person.m.

Person.h is a rather small file. Open it; it will look like the following:

#import <Foundation/Foundation.h>

@interface Person : NSObject

@end

All files with the .h file extension are called header files. A header file tells the rest of the program about the elements in your class, such as variables and methods. The various portions of the header file are explained as below.

#import <Foundation/Foundation.h>

This is an import statement, which you’ve seen before. It simply imports the basic Foundation class which your app requires.

@interface Person : NSObject

The above line informs the rest of the program that you are making a class called Person. The colon indicates that you are creating a subclass and the NSObject part indicates the class you are subclassing from. NSObject is a basic Objective-C class which can be used to represent an object. It has a few methods and properties which can prove useful in many different scenarios.

But you might be wondering what subclassing is. Subclassing is a way to derive a new class based on an existing class. The new class inherits all the existing attributes of the superclass (that’s the name given to the original class) but it can also define new attributes.

@end

The last line indicates that you are done defining the class. Everything between the @interface line and the @end line describes what is contained in the class.

Working with Instance Variables and Methods

Your Person class needs to store three different things: the first name and last name will be strings, and the age will be an integer. Modify the @interface block as shown below:

@interface Person : NSObject {
  NSString *firstName;
  NSString *lastName;
  int age;
}

The curly braces surround the instance variables of the object. Each Person object in your app has their own distinct set of data; they definitely don’t share names and ages! Instance variables store the individual characteristics of each object. Class variables, on the other hand, are shared amongst all objects of a particular class.

That takes care of storing a person’s data. Now what methods should your Person class have? At a minimum, you’ll need to set and retrieve the person’s information.

Add these lines right above the @end line:

- (void)enterInfo;
- (void)printInfo;

This defines the methods that your class provides to set the person’s data — enterInfo — and to print the person’s data — printInfo. You don’t need to flesh out the methods here in the header file; you just need to declare that they exist.

What does (void) mean before each of these method declarations? Recall that int main states that the return value of main is of type int. (void) indicates that these methods don’t return anything to the caller.

That does it for the header file. Now open Person.m. The file should look like this:

#import "Person.h"

@implementation Person

@end

This is the implementation file where the source code for your class lives. Looking at the file line-by-line, you will see the following:

#import "Person.h"

This imports the class declarations from your header file, in exactly the same way that you imported the Foundation classes in the header file.

@implementation Person

This indicates the start of the implementation block that contains the meat of your class.

@end

This simply indicates the end of the @implementation block.

That implementation file looks pretty empty. Time to add some code! Add the following code after the @implementation line:

- (void)enterInfo {
    NSLog(@"What is the first name?");
    char cstring[40];
    scanf("%s", cstring);
    
    firstName = [NSString stringWithCString:cstring encoding:1];

    // more code for the other fields to come later...

}

- (void)printInfo {
    NSLog(@"First name: %@", firstName);
}

The two methods above should look pretty familiar. enterInfo will prompt the user to enter a first name and then store it in the firstName instance variable. printInfo uses the familiar NSLog call to print out the stored first name.

This is a good time to test your class by calling it from the main function. Open main.m and add the following line to the top of the file, immediately underneath the #import line::

#import "Person.h"

By importing Person.h, you’ve told main about the existence of your new Person class.

Now add the following code just after the @autoreleasepool line:

Person *newPerson = [[Person alloc] init];

[newPerson enterInfo];
[newPerson printInfo];

The first line in the code above creates a new Person object. You’ll see the alloc / init combination a lot in Objective-C; alloc allocates memory for the object, while init creates and initializes the object that will live at that memory address.

The next two lines send messages that call your new methods. The program will first ask the user to enter a first name and then print it back out to the console.

Run your project, and when prompted, enter a first name. Your console output should look similar to the following:

What is the first name?
Michelle
First name: Michelle

Hey, it looks like your object is working as designed! Now you just need to flesh out the rest of the implementation.

Open Person.m, and add the following lines below the comment // more code for the other fields to come later...:

NSLog(@"What is %@'s last name?",firstName);
scanf("%s",cstring);
lastName = [NSString stringWithCString:cstring encoding:1];

NSLog(@"How old is %@ %@?", firstName, lastName);
scanf("%i", &age);

The code above prompts for the person’s last name and age and stores the data in the matching instance variables.

Finally, replace the printInfo method’s NSLog line with the following:

NSLog(@"%@ %@ is %i years old", firstName, lastName, age);

Run your project, and enter some data when prompted. Your output should look similar to the following:

What is the first name?
Jane
What is Jane's last name?
Smith
How old is Jane Smith?
23
Jane Smith is 23 years old

The Person object is doing exactly what you would expect. However, the app only stores information for one person. That’s not too useful; you need to allow the user to enter information for as many people as they would like.

Mike Jaoudi

Contributors

Mike Jaoudi

Author

Over 300 content creators. Join our team.