iOS

How to interpret iOS reference documenation for better app design

As an iOS developer, you need to understand how to read API or proprietary code documents.

The toughest part for me when I started programming apps was reading the Apple Documentation on iOS or MacOS. When I got into more APIs, things got even more complex. You need to understand how to read API or proprietary code documents in order to understand how to create a piece of code, connect to web services, or debug changes in code.

For example, you will very often see the term DEPRECATED, which means a particular method name is no longer used. This is very important, so let's take a look at Apple Docs first. (Figure A)

Figure A

TableViewController Class

Every class has a Reference document, which tells a developer what that class' methods and properties are. In this case, the above tells us that the object of type UITableViewController (UITVC):

  • Is a subclass of UIViewController
  • Adopts the table view Delegate and DataSource protocols
  • Requires the UIKit framework
  • Has some extra reference docs and samples

Notice on the left side bar there is a list of Tasks, Properties & Instance Methods. This tells us a bit more about what a UITVC object can do. For example, we see that it has an initWithStyle method, which is an (-) Instance Method. Other objects such as NSArray can have both (-) Instance Methods and (+) Class methods but they are all listed here.

Let's analyze the main Instance Method, initWithStyle. (Figure B)

Figure B

UITVC initWithStyle method

As we mentioned above, sometimes you will run into the infamous DEPRECATED warning. This means this method has fallen out of use and typically replaced by a better method. If a method is deprecated it will usually have a red label next to it specifying what version of iOS it was deprecated in.

  • In this case this method is NOT deprecated. So let's take a gander:
  • We get a brief description of what it does.
  • Then it gives us its method signature, which is to say, what code we use to implement it.
  • In this case it also takes a parameter named style. It gives us the two options for that parameter.
  • We are also told it returns a UITVC object or nil which is useful. This is important because if you are using this method to assign its result to another object, you better be sure what kind of result the method returns.
  • Finally it tells you where you can find sample code.
Now let's look at a more complex object, such as NSMutableArray. (Figure C)

Figure C

NSMutableArray Class Reference.

There are quite a few differences.

First off, notice this is from the Mac Developer Library instead of the iOS Developer Library as indicated by the top left icon and label. That's because this object exists in the Mac OS as well. Whereas UITVC is an iOS object.

Second, you can see that one of its methods is deprecated in OSX v.10.6.

Finally, notice this object has both instance and class methods. So let's explore one; an object's most basic method, init. (Figure D)

Figure D

This means that if you call our standard way of creating any object:

Object Class *objectPointer = Object Class alloc

And then we insert that method signature

-(id)initWithCapacity:(NSUInteger)numItems

So, we get this:

Object Class *objectPointer = [[Object Class alloc] initWithCapacity:(NSUInteger)numItems];

Let's look at the correctly formatted code:

NSMutableArray *myArray = [[NSMutableArray alloc] initWithCapacity:10];

Notice we took out the -(id) at the beginning of the method signature because we want it to return an NSMutableArray object. And the reason we can add this method signature to the NSMutableArray *myArray creation line is because we know that NSMutableArray contains that method signature inside its Class file. Finally we passed in the value for the parameter, initializing our array with 10 slots.

Jump To Definition

Sometimes we don't know much about a class we might be using in a project. Perhaps we want to know what methods we can call on an object. This is where Jump To Definition in Xcode comes in. If the class you have imported into your project does not have such nice Reference Docs as Apple, then you can place the cursor over the method or object and select Jump to Definition. This takes you to the base class where that object or method is defined.

Let's do that for an example I just ran across. I had been working on a game using Cocos2d. Cocos2d is an external library or third party framework. These terms are usually interchangeable but they "basically" mean the same. It's basically what you get when somebody or some company works on a bunch of code that helps you perform certain tasks.

For example, Cocos2d creators worked on many Classes to create Cocos2d. One such class is CCAnimation, which takes in various frames and strings them together to create an animation. They recently released v.2.0 and this particular class changed some of its method signatures to include improvements I guess.

If I open my code in Xcode and try to run my old code using v2.0 of Cocos2d, it crashes saying "Unrecognized Selector sent to instance". (Figure E)

Figure E

CCAnimation Errors in Cocos2d v2.0
This means that instance of CCAnimation doesn't recognize that old method or selector. Presumably because they changed the old name to accommodate new structural changes. So I right click over the CCAnimation call in my code where the app crashed. (Figure F)

Figure F

Jump to Definition in XCode
And when I Jump To Definition I am taken to the Class Implementation file. (Figure G)

Figure G

GG
CCAnimation Class File

This gives me the Class Reference for CCAnimation, the one being used in my project, and tells me which methods the class now implements. Now I just find the method that more closely matches my needs.

It's important to learn how to go from a crash to the documentation that can help you fix that crash. You basically need to understand what the reason for the crash was (which appears in the console) and apply logic and experience to sort through the reference documentation to replace your old or faulty code with the correct one.

Design strategy

It's important to keep your code clean and orderly. This is hard to do if you start coding without a design blueprint in mind and even then it can get messy. You will get what is called spaghetti code. So here is a very quick and simple tip.

I normally start out by making a paper and pen sketch of the layout. If you have read some previous posts or looked into my course at Learnable.com, you will have seen I start my apps with a hand drawn layout. I don't use digital tools for that because you can't beat the sketch-erase flexibility of a good old-fashioned scratchpad.

Anyway, here is the tip: Once I have the layout and I know the names of my classes, I use comments to place ideas. In other words, I open up my initial view controller (iOS app) or main action layer (game) and I start entering lines of code like this:

//Call Create an enemy

//Call Method to make enemy move

//Call My Main Player

//IF time = z then Call Create Powerup

By using comments to start coding, you can go through the ideas in your head (which flow profusely) down on 'paper' before it leaves your head. Later on you can go back to those comments and analyze them in order to determine what to call the method and which parameters to include.

Notice for example I didn't say, IF time...create health power-up. I said Call create power-up because this way I can outsource these things to generic factory methods.

We can assume every piece of code grows to be evermore complex. In the case of a game, power-ups can start with just one kind (a health pack) but eventually you may have red, blue, and gold health packs or various power-grade guns. This means you will want to create very generic methods such as createPowerups instead of createHealthPacks. This is mostly because certain objects will share many common tasks.

Furthermore, if you have organized your classes correctly, you will be able, for example, to pass in a Class Object name to a generic method and have it create that object for you at a given time and place.

Consider the following scenario. You have different power-grade guns in your game or app. At first you simply say something like:

-(id)createRaygun;

But as your project grows and your guns get more complex, you would end up having dozens of different gun methods. It would be convenient to have a more generic method with more parameters such as:

-(id)createGunWithImage:(UIImage*)image ofColor:(NSString*)color withPower:(NSNumber)power;

This way you can call the gun creating method and pass it a few parameters and get a different gun every time, which is much cleaner than having many different gun methods.

These things may seem very obvious but when you get to coding a game, or app, your idea is fresh in your head and you don't want Strategic Planning to slow you down. Otherwise you end up with spaghetti code. What you want is to get your ideas down "on paper" first. Then worry about making those ideas happen.

Planning ahead of coding

The reason is that you get caught up in figuring out HOW to Call Make player move. Most of the times you don't know how to do something right off the bat or you get caught up in something silly like declaring ivars versus properties or you can't recall the exact name of the method signature you had in mind to do something. By the time you get it right, you've lost track of what you were doing.

So this is what I do; I take all my ideas and comment them in the init method. Then I start creating the respective empty methods to carry out each one of those ideas. For example:

-(void)createMainCharacter{
//Fetch image (from atlas or file & from own subclass)
//AddChild to layer (or batch node)
//Position and call character's initialization methods
}

This way I can see what needs to be done inside my layer and what I can do in another method or subclass. In this case I may end up calling my character from its own subclass instead of just saying CCSprite *myCharacter. This also helps me leave out specifics that belong in that subclass so that I don't clutter up my init method or layer class with object specific code.

In other words, I wrote I needed to position my object and call its player initialization methods. This means those methods to do initialization stuff for that object must reside outside of my layer, ergo, the object subclass methods.

I think this is a good tactic to creating games and apps because, believe it or not, they will get more complex, even if you don't intend them to. That will make your code unreadable in the future and with API changes or new ideas, your code will be much easier to modify.

Bookmark this article because I bet you a few months down the road, specially if you are getting started, you will find yourself drowning in spaghetti code. You will be glad you did!

Also read:

About

My name is Marcio Valenzuela and I am from Honduras. I have been coding in iOS for 5 years and I previously worked on web applications in ASP and PHP/mySQL. I have a few apps up in the app store and am currently working on a couple of Cocos2d games...

0 comments