What Are The Two Biggest Complaints That Frustrate Newbie iOS Developers?

Does this sound familiar?

“I would love to do iPhone development but I just don’t have the time to wade through the obtuse and elitist tools required to master iOS programming.”

I’ll bet this describes at least some of you out there right? The reason I know this is that late last year I asked my readers what their biggest sticking points were. The overwhelming response to this question could be summarized by two words: Time and Tools.

Who Has A Massive Time Surplus?

The answer to this is: almost no-one. Maybe if you’re still a student or a recent grad and are very excited about mobile development then you can learn app development instead of burning away hours on the XBox (or whatever you kids are doing these days!).

However, most of the people who responded to my survey though already have tons of completing burdens on their time: family, jobs, hobbies, activities, babies and so on. For this group, taking a few months to struggle through learning something brand new is daunting. Almost no-one has the 6 months to a year it would take to learn this stuff on their own.

Some of the responses I got were:

“No time to explore mobile technologies though I’m trying hard to devote time for this.”
“Having time to work on iPhone apps.”
“Not having enough time.”
“Time. As a father of a young family with many constant and various needs. Husband. Working professional. Like many others.”

Trying to learn something brand new like iOS development on your own is going to take a ton of time. Obviously, learning a new skill will take some time – the question is only how much time will it take?

What’s the solution?

If you’re truly motivated you can find some time in your schedule. Here’s some ideas:

– Re-Prioritizing Projects (maybe that new bathroom can wait a few months)
– Getting Help With Chores (hire a cleaning service and/or a handyman and use your time savings for your education)
– Use your educational time wisely (investing in the right class or training program will be much better than wading through on your own)

The only way around the time problem (outside of magic spells) is to get help so that you use your time wisely.

The Comfy Tool Bias

This applies especially to seasoned software developers. We all have our favorite tools and have mastered our workflow to the point where making new software is as familiar to playing a favorite video game. Other professionals have similar feelings with their own workflows and tools.

Xcode, Objective-C, iOS and UIKit are the four main tools you’ll use to make apps. For most newbies, these tools are unlike anything they’ve worked with before. These are not your typical text editors, photoshops, Visual Studios or Microsoft Words. Many (if not all) newcomers find these tools daunting.

In fact, the words I used at the beginning to describe these tools sum it up pretty well: they seem elitist and obtuse. The truth is: they are. For a programmer used to performing magic feeling lost and stunted with Xcode is overwhelming. For a newcomer to software development who hasn’t used a Mac the experience can be terrifying.

What’s Your Opinion?  What is the biggest sticking point that you see with new iOS developers?  Please comment below…

Understanding Subclassing

This means that if you have code in one class that you would like to reuse in another class you can create a subclass. The original class is called the superclass and the subclass gets all the code in the superclass. You can also add additional code to the subclass. Programmers do this all the time which creates a hierarchy like the graphic at the top of this page.

The Super And Self Keywords

If you haven’t yet groked the relationship between classes and objects the details of this can get confusing. For instance, take a look at the init override that you get from Xcode’s code library:

-(id)init{
    self = [super init];
    if (self) {
        //initialize here
    }
    return self;
}

NOTE I’m assuming you know about how to create classes in Objective-C here. If you don’t know what I’m talking about click here to read the chapter on creating classes in Objective-C.


So I highlighted some particularly confusing keywords that are in theinit function.self andsuper reference objects from the class that we are currently defining.

While both keywords objects created from the class self references the properties and methods defined in the current class definition while super references the properties and methods defined in the superclass definition.

Objects And Classes

Let’s take another look at that init override so we can see the context where we usually see this function.

#import <Foundation/Foundation.h>

@interface MyClass : NSObject

@property(strong) NSString *name;

@end

@implementation MyClass

-(id)init{
    self = [super init];
    if (self) {
        //initialize here
        _name = @"MyClass Object";
    }
    return self;
}

@end

int main(int argc, const char * argv[]){
    @autoreleasepool {
        MyClass *myObject = [[MyClass alloc] init];
        NSLog(@"myObject.name = %@", myObject.name);
    }
    return 0;
}

Here’s the English version of the code above: we defined a class named MyClass which is a subclass of the NSObject class. MyClass is going to override the init function.

In the main function we are going to instantiate an object named myObject and write out the myObject name value to the console log.

Class Vs Object

A class is a definition of an entity (an abstract model) that is made up of definitions for properties and methods. By itself, a class doesn’t do much other than contain a definition. In the above example all the code that defines the class is between the @interface and @end keywords and the @implementation and @end keywords.

Objects are special variables that are created based on class code definitions. You can see how objects are used in the main function above. Typically, you would create many objects based on one class definition.

How It Gets Confusing

This stuff gets confusing because most people think of classes and objects as the same thing. After all, when you want an object to behave differently you must make changes so rewrite the class definition. So that’s pretty natural. Getting back to the init function though you can see why this gets confusing,

-(id)init{
    self = [super init];
    if (self) {
        //initialize here
    }
    return self;
}

In that first line of code after the function name, self = [super init];, it looks like we are getting an NSObject object from the superclass, assigning this object to self and then returning this to the caller.

This is not really the case. You are simply getting your MyClass object from the superclass. The reason that it seems like you are getting an NSObject object back here is because you are thinking in terms of objects and not class definitions. Even though this code will be used to initialize and return objects at some point right now we are only working on the code definition.

That self keyword doesn’t represent some NSObject object variable out there. It’s simply a way to reference the code from the superclass definition.

What subclassing really does for you is more like a copy and paste. It’s as if you have copied all of the NSObject code and used this code in MyClass. So that init call to super will just initialize the part of the class definition that is contained in NSObject before you finish up initializing.

Chapter Nine: How To Create Your Own Classes

At some point you will want to define your own classes to use in your app. So now let’s expand on the notion of object oriented programming by showing you how to implement your own custom classes. At this point you should be familiar with using existing objects in code; but you also need to be able to create your own types of objects.

Sub-Classes

One of the most common things that you will be doing with classes is something called sub-classing. As you can guess the iPhone has classes already in place to do things like present data tables, present windows and so on. Usually you will be creating your own object that inherits one of these preexisting objects and adding your own custom code to it. This is sub-classing.

Adding a New Class

XCode will help you do the initial set up work when you are creating a new class. To add a class you can simply control-click on a group folder in XCode and select New File… . In the dialog box that pops up select iOS > Cocoa Touch > Objective-C class and click Next . Then name your class and choose NSObject as the subclass.

Let’s do this now and call our class myClass. XCode created both the interface and the implementation files for myClass and added the code we need to get started. The interface file is the one that ends in .h. If you open that file you will see the code that XCode automatically filled in for us.

#import <Foundation/Foundation.h>

@interface myClass : NSObject{

}

@end

Interface File

This interface file uses an import directive to import the Foundation classes (which we always need to use). It also uses the interface keyword with the name of the class (myClass here) to indicate that we are defining a class.

The colon and the name NSObject means that our class will be a subclass of NSObject. Sub-classing and inheritance mean the same thing. You can say that myClass inherits from NSObject or you can say myClass is a subclass of NSObject.

We end the interface declaration with the end keyword @end.

Implementation File

XCode also created an implementation file, in case you did not notice XCode will create a separate file for the interface (header file that ends in .h) and the implementation file (ends in .m). Click on the implementation file to see the code that XCode added on our behalf.

#import "myClass.h"

@implementation myClass

@end

Our implementation file simply imports the myClass interface and includes the @implementation and @end keywords along with the name of our class.

Simple enough – we have created our first class. Right now it behaves exactly like NSObject, but soon we will be adding our own properties and methods to the class.

Adding Properties

When you add a property in a class you end up using a little black magic. That is, the system takes care of some of the implementation details for you if you do things in the typical way. You need to do two things to get a working property into your class: declare the property and then use @synthesize.

Here is what this looks like in the code:

Interface File (myClass.h):
#import <Foundation/Foundation.h>

@interface myClass : NSObject

@property (strong) NSString *name;

@end

The property is defined by using the @property directive. The key thing to note here is strong.

Back in the implementation file we use @synthesize to evoke all the black magic that is required to create the property based on our definition in the interface file.

#import "myClass.h"

@implementation myClass
@synthesize name;

@end

One thing that is significant though is that when you use primitive types as properties the syntax is a little different. For example, I am going to add a number property to my class that is an integer. Notice that it is done in a slightly different way:

#import <Foundation/Foundation.h>

@interface myClass : NSObject

@property (strong) NSString *name;
@property (assign) int number;

@end

The first thing is that there is no asterisk * since this is not an object variable. The other thing is that instead of using the strong keyword it is using assign in the property declaration.

Dot Notation

What all this does for you is give you the ability to assign and retrieve the property values using dot notation. You have already encountered this in the examples. Here is how you use dot notation with a myClass object.

//Instantiate an object from myClass:
myClass *object = [[myClass alloc] init];

//assign properties:
object.name = @"Obie";
object.number = 3;

//Access and use the properties
//with dot notation:
NSLog(@"My object's name is %@", object.name);
NSLog(@"My Object's number is %i", object.number);

Note that we use an alloc and init message even though we never created these in our class definition. Since our class is a subclass of NSObject we can simply use the original NSObject constructer to create objects. We can also code additional constructors if we want to set properties before we return our object to the system.

Class Methods

As you remember from chapter ten , objects have both properties and methods. Properties describe the object (the object’s attributes) while methods are what the object does (the object’s behaviors).

Furthermore, methods can be either class methods or instance methods. Class methods do not require an instance of a class (an object) to be used, you simply send the message to the class itself.

Here is how to declare a class method:

Interface File:

#import <Foundation/Foundation.h>

@interface myClass : NSObject

@property (strong) NSString *name;
@property (assign) int number;

+(void)writeSomething;

@end

Implementation File:

#import "myClass.h"

@implementation myClass

@synthesize name, number;

+(void)writeSomething{
	NSLog(@"I'm writing something");
}

@end

Here, the plus sign indicates that this is a class method and the void in between the parenthesis means that the method will not return a value. This is followed by the name of the method and curly braces. Whatever we want the function to do we put in between the curly braces as code.

Since this is a class method we do not even need an object to use this method. All we need to do is send a message to the class name itself:

[myClass writeSomething];

Instance Methods

Instance methods also are used to code behavior, but these are different than class methods because they may only be used by sending a message to an object. You code them the same way inside the class definition but you prefix the method with a minus sign instead of a plus sign:

Interface File:

#import <Foundation/Foundation.h>

@interface myClass : NSObject

@property (strong) NSString *name;
@property (assign) int number;

+(void)writeSomething;
-(void)writeSomethingForAnObject;

@end

Implementation File:

#import "myClass.h"

@implementation myClass

@synthesize name, number;

+(void)writeSomething{
	NSLog(@"I'm writing something");
}

-(void)writeSomethingForAnObject{
	NSLog(@"I'm writing something, but only as an object");
}

@end

To use an instance method we must have an object available.

myClass *object = [[myClass alloc] init];
[object writeSomethingForAnObject];

Method Parameters

Like functions in C you can pass parameters to methods in Objective-C. The syntax looks different. To put a parameter into the method declaration you must add a colon after the method name and then declare the object type and name the parameter:

Interface File:

#import <Foundation/Foundation.h>

@interface myClass : NSObject

@property (strong) NSString *name;
@property (assign) int number;

+(void)writeSomething;
-(void)writeSomethingForAnObject;
-(void)aMethodWithThisParameter:(NSString *)param;

@end

Implementation File:

#import "myClass.h"

@implementation myClass

@synthesize name, number;

+(void)writeSomething{
	NSLog(@"I'm writing something");
}

-(void)writeSomethingForAnObject{
	NSLog(@"I'm writing something, but only as an object");
}

-(void)aMethodWithThisParameter:(NSString *)param{
	NSLog(@"%@", param);
}

@end

To use this method you would do this (this will be familiar to you):

myClass *object = [[myClass alloc] init];
[object aMethodWithThisParameter:@"Say What?"];

Multiple Parameters

You may have your methods take more than one parameter. Objective-C has a unique way of doing this where you may include a descriptive phrase in the method declaration.

Interface File:

#import <Foundation/Foundation.h>

@interface myClass : NSObject

@property (strong) NSString *name;
@property (assign) int number;

+(void)writeSomething;
-(void)writeSomethingForAnObject;
-(void)aMethodWithThisParameter:(NSString *)param;
-(void)aMethodWithThisParameter:(NSString *)param 
		   andThisParameter:(int)num;

@end

Implementation File:

#import "myClass.h"

@implementation myClass
@synthesize name, number;

+(void)writeSomething{
	NSLog(@"I'm writing something");
}

-(void)writeSomethingForAnObject{
	NSLog(@"I'm writing something, but only as an object");
}

-(void)aMethodWithThisParameter:(NSString *)param{
	NSLog(@"%@", param);
}

-(void)aMethodWithThisParameter:(NSString *)param
               andThisParameter:(int)num{
	NSLog(@"%@ + %i", param, num);
}

@end

The key difference between methods with one parameter and methods with two is that starting with the second parameter each gets its own descriptive text prefix. Above it is andThisParameter: which is in front of the parameter num.

Your probably already guessed that you send a message to an object using two parameters like this:

[object aMethodWithThisParameter:@"One" andThisParameter:2];

Constructors

We know that constructers are special methods that return an instance of an object back to the system. We are already using the constructer that we inherited from NSObject, init to instantiate an object from myClass. We can create a custom constructor if it is needed.

In general, we always prefix our constructor with init. This is a matter of convention. Let’s start by defining our constructor in the myClass implementation file:

#import 

@interface myClass : NSObject

@property (strong) NSString *name;
@property (assign) int number;

+(void)writeSomething;
-(void)writeSomethingForAnObject;
-(void)aMethodWithThisParameter:(NSString *)param;
-(void)aMethodWithThisParameter:(NSString *)param 
				andThisParameter:(int)num;
-(id)initWithName:(NSString *) aName;

@end

Instead of being declared as a void type as our previous methods our constructor will be declared as an id. id means that our method will be returning a value that not yet defined. Whenever you replace the void with another type you are saying that this method will be returning a value (like a function in C).

Our constructor will also be taking a parameter which we will use to assign a name to the object’s name property. Here is how we implement this constructor:

#import "myClass.h"

@implementation myClass
@synthesize name, number;

+(void)writeSomething{
	NSLog(@"I'm writing something");
}

-(void)writeSomethingForAnObject{
	NSLog(@"I'm writing something, but only as an object");
}

-(void)aMethodWithThisParameter:(NSString *)param{
	NSLog(@"%@", param);
}

-(void)aMethodWithThisParameter:(NSString *)param 
				andThisParameter:(int)num{
	NSLog(@"%@ + %i", param, num);
}

-(id)initWithName:(NSString *) aName{
	if (self = [super init]){
		self.name = aName;
	}
	return self;
}

@end

In the if-then statement above we assign the object returned from the constructor that we inherited from NSObject to the current object (notice that there is only one equals sign). The self keyword always refers to the object in which the self keyword was placed while the super keyword refers to the class it is being inherited from (sometimes called the superclass).

Once we have successfully retrieved the object from the super init we can assign values to our properties.

Here is how you would use your new constructor to create an object:

myClass *object = [[myClass alloc] initWithName:@"MyObject"];

Hands On Time

Practice creating your class by first thinking all some attributes and behaviors could represent a person in your code. Keep it simple but meaningful. Use the techniques that you learned in this chapter to create a class definition for a person. Instantiate and use objects created from this class definition. Try using a NSMutableArray to hold a list of your person objects.