23. The power of for-loops in action

How are you feeling about for-loops? They making okay sense? I want to further drive the point home about how awesome they are by giving an illustration of a problem I faced recently. This post will be more of a quiz than anything else, but I feel like it will be useful.

Let me start by describing the scene. I was doing some OS X development (which is basically the same thing as for iOS as far as logic goes) and I ran into an interesting issue.

I had a window that I needed to be able to dynamically add subviews to. I needed to be able to hand this empty window an array of views, and have it lay them out display them correctly. To make the math simple, each subview in the array is 100 px tall and as wide as the outer window.

So if the array has one item in it when it is time to size the outer window, how tall is the outer container going to be? 100 pixels. So if their are 5 objects in the array, how tall does the outer window need to be? 500 pixels. Pretty easy.

The interesting part comes when you understand that the OS X coordinate system is opposite that of iOS. That means that (0,0) is on the bottom-left as opposed to the top-left like in iOS. To make things more interesting, I need to have the object that is at the 0 position in the array to always be at the top of the window.

If you think about it for a minute, can you come up with the basis for the logic we will need to put into this layout effort? We are definitely going to need a for-loop. Why is that? Well, we need to iterate through each view in the subview array and set it's y coordinate value to a certain position. This is easily achieved with a for loop. I'll go ahead and give you some basics to start off with:

Hopefully that isn't to hard to see what is going on. We are iterating through our array of view objects (NSView is the equivalent of UIView in OS X programming) and are using the setFrameOrigin: method to set the (x,y) values of each view we see.

We have everything in place to solve our problem. We don't need to worry about the x value, that stays the way it is. We do need to worry about the y value though. This is where the quiz comes in.

  1. Can you tell me what is wrong with the current code that is setting the y value like this: i * 100 ? Keep in mind, we want to have the object at index 0 be at the top of the view that originates from the bottom. And if there is an object at index 1, it needs to be below the object at index 0 in the view hierarchy, etc.
  2. What could we do (there are a few different ways of accomplishing this) to fix it so that our problem is solved? So that we are displaying our subviews correctly?
This type of exercise is a great way to evaluate your ability to reason through logical dilemas. Send me an email or leave a comment if you have questions or if you want to make a stab at the answer. I'll post the solution later on.

22. The for-loop

This topic is another one that took my brain a while to digest. The for-loop is an incredibly powerful and useful tool that you will find yourself needing/using all the time. It may be a little tricky to get the hang of at first but you can do it.

Let's start by recalling the situation we are in that necessitates the use of a for-loop. We need to build a big huge array and we don't want to build it by hand. To give you an idea of what I mean by hand consider this code:

Based on our exhaustive discussion that we have had on methods and method calling, can you describe what is going on here? We are calling the addObject: method on our srtrings NSMutableArray object. For each time we call that method, we are adding a string object into our array.

Based on this example, you can see how it would take a ton of work to build this array by hand. Lots of copy/paste and annoying editing. But the good news is that we don't have to do it that way! We can use a for-loop and our lives will be insanely easy.

Let's take a look at the structure of a regular (there are a few different variations) for-loop:

That's it. It doesn't look that bad, right? If you put that code into your app's viewDidLoad method, do you have any guesses what your console would look like? Let's talk about what is going on. After the for declaration, there are three separate components within the (), separated by ;'s. This is important syntax you need to get just right. We declare a local variable of type int name i that we give a value of 0. It's name and value can be anything you want. Standard convention (for whatever reason) is that you name it i, and we want 0 because that is where we start.

The purpose of a for-loop is to give you a control mechanism for-looping through some code a specified number of times. Based on our next condition i < 1000; how many times are we hoping this for-loop loops for us? from 0-999, or 1,000! Do you see how that works? This for-loop is looking awesome.

The final condition i++ does what the ++ command does everywhere else. It increments an int. So we start off our loop at 0, we make sure that i is less than 1,000, and if it is we run through the course of the loop, executing whatever code is in there, and after we run through once, we call i++ to say we have finished that round of looping.

The result is a useful tool that lets you easily control how many times to iterate over a specified bit of code.

So let's remember our goal of building this massive array of strings. Without me telling you what to do, can you think of how to put the pieces together and solve our problem? If not, that's ok. We will go over it. We want to declare the array once outside the scope of the for-loop, and then inside the for-loop we want to call the addObject: method 1000 times to build up the array. Check this out:


How cool is that?! You are going to love for-loops. They rock. Is there any part of that that isn't making sense? Can you see that because we are within the scope of the for-loop that we have access to the i integer? So at any point within the scope of the for-loop we have access to the iteration number that we are currently on. That number is called the index. Say that word 10,000 times over and eat it for breakfast. Index. Index. Index. You need to be able to use that word as interchangeable as your thumb. The index refers to the position in the array that you are currently at.

So let's tie up one last loose end before everything comes together and you will sit there in awe and wonder because of how useful arrays and for-loops are. We have just built our array of 1,000 strings, now what? How does that help us in our current project?

Remember I said the term index is very important. Whenever we hit the plus/minus button in our app, we are changing the value of a counter variable, right? This can be our index!! All we need to do is to set the label (the same code we already have inside of all of the if statements) to the value of the string that can be found in the array at index:count!

Try and figure that out. See if you can piece together the rest of this project. Are you seeing how cool this stuff is? Well, let me tell you, we are just getting started. The coolness will continue!

Ok, enough blabbing. Here is what I am talking about:

Assuming that we built our NSMutableArray as a global variable up in the viewDidLoad: method, we have access to both the array and the index variable we need, and the method objectAtIndex: goes into the array and returns whatever object is at the index position you are giving it. Pretty slick!

It is very important to know that your app will crash if you ask for an object at an index that doesn't exist. That is why I had the if statement there making sure that it wouldn't ask the array for it's 1001th object. We know it didn't have that many object so we aren't even going to ask!

Stay tuned for more goodness to come.

21. Arrays - A programmers best friend!

Let me take you back in time to when I was a senior in high school. I was taking a computer programming class from a math teacher that was incapable of speaking in terms I could understand. I literally couldn't understand anything he was talking about for the entire semester. He would just stand up and ramble on and on about crazy stuff that I had no clue about.

Throughout the course of the semester, I was basically able to master the basic variable types, printing messages, and if statements. That was it. I remember hearing people talk about these things called arrays. I had no clue what they were talking about but the sound of the word made me want to run for my life because it was just another layer of complexity that I wasn't ready to take on at that point.

As we begin our discussion about arrays today, I want to assure you that there is nothing to be scared about. In fact, by the end of this lesson, you'll be laughing at me for ever being intimidated by arrays. They are one of the most useful and pervasive objects that we can use in iOS development, so let's dig in deep and make sure we understand them!

Simply put, arrays are containers. Look up at the image I added to this post. Filing cabinets are a good way to envision what arrays are because filing cabinets aren't anything particularly interesting by themselves, but they become important and useful when you have things to put inside it! So think of an array like a filing cabinet for now. It holds things.

What does it hold?

A fine question. Without going too deep into particulars that don't really need to be discussed right now, there are a few different types of arrays. Apple has done a lot of work writing classes and making easy-to-use API's for different objects that make our lives as programmers a lot easier. The NSArray (notice the similarity in name to NSString) is just such a class. The NSArray is an array like any plain old C array, but Apple has beefed it up with lots of extra features and goodies that we really benefit from. So to go back and answer the original question, NSArrays can only hold objects. This is very important to remember. We can't stick primitive data types (ints, doubles, booleans) inside of an NSArray. We can stick objects in the array just fine. That is what they are made for.

I've mentioned before that there are a bazillion different types of objects that we can use in programming, and we can even make our own types of objects (which is where object oriented programming becomes very powerful) but what is the type of object that we have worked with that you're most familiar with? NSString! We are going to go ahead and make an NSArray object and fill it up with some NSString objects and show you how awesome we can spruce up our previous app.

NSArray is an object

Ok so it needs to be understood that the NSArray is an object. It is an object whose purpose is to hold objects. If this doesn't really seem that intriguing, I promise it will. Whenever we are dealing with objects, we need to remember that creating them is done a little differently than primitive data types. If you recall, with something like an int, we could just declare 'int i;' and all is well! We can begin assigning values to i immediately.

But with objects, it isn't so easy. When you make a string like this 'NSString *myString = @"hello";' you might think that the myString variable is 'hello'. That is what it is and that is it's value. That is basically true, but the funny thing about that little * we've seen a few times is that it implies that the myString variable isn't exactly that value but a pointer or reference to the address in memory of where that value can be found.

Wow. You still with me? This idea causes a lot of problems for a lot of people. To be honest, it isn't something that you need to really worry about all that much at the moment, but as we dive into understanding more about objects, it is important to understand that the variable name you see is usually pointing to a place in memory where the value you want can be found.

So an object needs to have a place in memory that it can live and store information about itself. A place to call it's own. Since this post is supposed to be about arrays, let's go ahead and make ourselves an NSArray:

NSArray *arrayOfStrings = [[NSArray alloc] init];

How does that look? Have we seen this alloc/init business before? You may have seen it already, but I don't believe we have talked about it. Understanding the importance of the above code is something I can't stress enough. Simply put, the alloc/init call makes room in memory for your new object and gets everything ready for first use. It is the literal act of building an object. There is a big difference between declaring the name of an object:

NSArray *array;

And actually building the object so that it can be used immediately:

NSArray *array = [[NSArray alloc] init];

Due to the fact that we are doing OO (object oriented) programming, and we are going to be using objects all over the place, it would be good to get used to the idea of using the above methods.

So thanks to the alloc/init code we now have a nice new shiny NSArray that we can use. Let's think in terms of the app we built in the last post. How can we optimize that app's logic to incorporate this new NSArray tool? When you think of the implementation of the logic we put into that app, doesn't something just jump out and scream INEFFICIENT to you? Yes. What is we didn't want to stop the incrementing at 10, but rather 100, or 1,000? Would you really want to make that many if statements? I've seen it done before, but trust me, you DON'T want to do that. We can use an array to solve this issue quite easily. But first we need to add data to our array.

In Objective-C (and the associated frameworks) you will see that there are often two different variations of the same object type. So where there is an NSArray there is also an NSMutableArray. Where there is an NSString there is also an NSMutableString. And so on.

This term mutable implies that the object type is editable, or that you have full read/write access to it. In the case of the non-mutable types, you can fill them up with existing data (like from a JSON/XML file or something), or you can add data in when you first alloc/init the object. But after you make it, you can't change it's contents. You can only read the objects in the array.

Other than that minor difference, they pretty much both act the same. So to use an NSMutableArray in this instance wouldn't cause any difficulty because you just add mutable to the class name and we need the ability to add objects anyway.

So, our goal is to optimize our last project we just worked on. Do you still have the code for it lying around? Our goal is to be able to handle up to 1,000 button presses, and not have it take several hours to do it. 1,000?! Even if we aren't using if statements like I'm suggesting, won't it take forever to build the array? Well, it can take forever, but it doesn't have to!

For our next topic, we will be diving into the for loop. An amazingly powerful tool that is really going to save our bacon.


Flashcards!

Ok this isn't another post on iOS material, but it is important! I just finished making a flashcard deck (through Quizlet.com) for the information we have been covering in this blog. I have found that reviewing material in this format is one of the best ways to get it really cemented.

Quizlet is also a really powerful tool. It lets you review terms in whatever format you like, and then you can quiz yourself by taking a test essentially that lets you iterate over the list of items until you have them all mastered!

Please note that this deck is by no means comprehensive. I would love to have your help in making this a more complete list. If you have something you would like to add to the deck, just send me an email or leave it in the comments below.

Please take advantage of this resource! I promise it will help. Good luck!

20. Building our SUPER basic app 3/3

Is your button printing to the console? I hope so. Let's move on and get that button to do something useful. We talked about the behavior that we wanted the button to accomplish. We press the button, and the number increments by one and displays a message based on that number. If you think about it, there are many different ways that we could accomplish this. For our purposes, we'll start out with the most basic I can think of: the if statement.

The purpose of the if statement is pretty simple. We use it to do a test on the result of an equation. What equation? Well that ties in with our discussion about logic. Consider this equation:

1 + 1 = 3

Does this equation evaluate to true or false? In other words, is the above equation right or wrong? It's wrong or false. That is easy. The important thing to realize is that we can do tests (mathematical or Boolean) to see if certain conditions exist, and we can act accordingly.

Lets think of an example of how we could use an if statement. When the user of our app first presses the button, and before we increment any variable values, what is the value of the counter variable? Well, we haven't set it to anything yet so it will default to 0. So the purpose of the counter variable is to allow us to conditionally display text to the user, right? We want to show different messages for different values. So let's add an if statement to our IBAction that handles our first case:



So this is pretty simple. As I mentioned before, this is basically the most simple way I could think to do this. That's okay thought because it exposes us to some more useful concepts.

If our count variable is == 0 then control enters the scope of the if statement and executes whatever is inside. It is important to understand that we don't use one = sign because that is the same as setting count = 0 which we don't want. We want to check if the logical operation of comparing the two values results in true or false. If true, enter the if statement, else don't.

What is this count++ wizardry you are probably wondering? Well, that is a shorthand way of incrementing a numbers numeric value. It is the same as saying count = count + 1 or in other words take whatever count is and add one to it.

Based on what we have so far, how many times do you think we could press our button and have that log message printed? Answer: one time! Because after it increments after the first pass, it is never going to be 0 again. It just keeps growing with every press.

So that solves part of our problem, now what about setting the number value to the appropriate label on our screen? Or what about setting a custom message? Think about that for a bit. Where would we put code that could handle that? If you said 'within the scope of the if statement duh!' you are totally right. When we enter the scope of that if statement, we want to update the values of our IBOutlets so that they can reflect the changes appropriately.

We've gone over this before, but do you remember how we can set the value of the UILabel objects? Think about it...

Ok, this is what you do:



By accessing the text property of the UILabel objects named messageLabel and counterLabel (remember we made those IBOutlets in the .h file (if you forget what you named a variable it is super easy and convenient to press ctrl-option-up arrow to toggle between the .h/.m file!)) we can change their values by passing a variable or object of the appropriate type.

Setting the value of the messageLabel was easy because the label needs a string, and the message we wanted to send it was a string! A perfect fit. But as you see, setting the counterLabel text was a little more difficult. The label is expecting a string and the counter variable that we are trying to send it is of type int, right? We will get an error if we try and send an int to a place where a string is expected. That is why I am using the nifty converter that NSString gives us. Similar to how NSLog works, we are basically converting our int into a string so that there aren't any problems. I highly suggest you become very familiar with the name of that method: [NSString stringWithFormat: ]; You will use it ALL THE TIME.

So now that we have that done, go ahead and run the project and you will see something happen when you press the button! That's pretty neat!

So what if we wanted to handle more cases? Well, keep going! You can setup else if statements to carry on through some more testing. So if the first condition fails, it will continue on to the next:


Go ahead and fill out the if-else if statement so that it can appropriately handle 10 button clicks! Fill in the messageLabel with whatever you want but make sure that the counterLabel is accurate.

For a bonus feature, try adding a decrement button! The syntax for decrementing is what you might expect: count--; Try hooking up a decrement button so that you can go up and down through your messages but so that you can't exceed 10 and you can't drop below 0. Just try it out! It will be fun!

19. Building our SUPER basic app 2/3

I bet you have just been dying to know the answer to the questions I posed at the end of our last post. In order to hook up our .xib file to the code side, how many IBOutlets and IBActions will we need?

Based on the description of the app, we need to be able to change the text content of the two labels. Do we need to change anything with the appearance of the button? That wasn't explicitly stated as a functional requirement so we're going to pass on that. So because we need to change our two labels, we will need two IBOutlets. And then because we are going to respond to one click action (from the UIButton), we will need one IBAction.

Before we dive into setting everything up, think back to a few posts ago where I asked about how we are going to keep track of what number we are on. Do you have an idea? Based on our discussions about variables, and their purposes, what could we use to keep track of our increment progress as we go through the app? Class variables! You got it. Can you see how those are going to help us? If not, you will soon. Click here if you need a refresher on class variables. So let's move on.

You should be able to hook these up on your own by now but I'll go through it anyway.

The first step to setting up the IBOutlets/IBActions is to declare them in the header file (.h file):

Can you tell what we are doing? Where is my class variable? This shouldn't look too foreign to you. Are we done? Nope! We need to implement our IBAction. So go ahead and copy the method signature and paste it into the .m file like this:

There are more methods below, I just wanted to show a basic implementation of our IBAction. Are we done yet? No! We have set everything up in code now, and we have prepped everything in IB as well, now we need to hook them together. Click here and here for a refresher on hooking them up. Basically, you just go into IB, right-click on Files Owner, and drag from the little circle that corresponds to the item you want to link to directly to the item. Try it out and don't forget to hook up the action as well!

When you save and build and run, you should see a message in the console for every time you hit the button. Don't worry, in our next post we are going to actually put some logic into our app so that it does something interesting when we press the button. make our button do something.

You're probably wondering why we're going through this again, but I promise it is necessary. Lot's of repetition makes for solid learning.

18. Building our SUPER basic app 1/3

We have gone over most of the topics that we will need to build our basic app, so let's refresh on what our specs are for this app:

"Let's make an app where we have a label that displays a number. We will also have another label that displays a different message based on the number that is displayed. And then we will have a button that we will press in order to increment the value of the number label which will in turn change the message label."

I hope that you tried to make some of this on your own because that is the best way to solidify these concepts. Doing it yourself after learning makes it cemented in your brain.

Based on some of the work we have been doing so far, we should already have a pretty useful skeleton to work off of. Lets build this app in stages:

1. Layout the .xib file. I like to lay everything out in IB whenever I can because that helps me get an idea of what I'll need to do to hook everything up in code. If you haven't already, go ahead and make something that looks like the image below. Feel free to poke around with some of the different tools in IB to enhance it and make it look better.


Ok, that is pretty basic looking, but it will do. Like I said, feel free to play around with the IB controls a little to make it look better. Here is a break down of each IB element:

A - This is a UINavigationBar. You can click and drag this item from the IB library and put your own custom text and color onto it right away. It is a very standard element that everyone who uses an iPhone has grown used to.

B - The UILabel associated with our custom message we are going to display.

C - The UILabel associated with the current number.

D - The UIButton we are going to press in order to increment the count and get everything going.

So that is the basic view of our basic app. What do we do now? Well, now that we know what we want it to look like, it's pretty easy to see what is next. We need to hook everything up to the code side! How many IBOutlets are there going to be? How many IBActions? Think about that and I'll answer it in the next post!

17. Logic

I am sorry that it has been a while since my last post. I am going to try and write more often.

The next topic we are going to tackle falls right in line with the direction we've been heading. In our last post, we were able to hook up a button to a method in our code and when we clicked the button, it did something! Pretty awesome. But, what did it do? It just printed out a dinky message to the console, right? I'm afraid that's not very awesome.

After all of the ground work that we have been laying so far, we are finally in a position to start writing some actual code. Or in other words, we need to put some logic into our app.

What comes to mind when you think of the word 'logic'? Some nerd at school who was always logical? Not exactly. In programming, the term logic is used to describe the process of mentally solving a problem and then representing that solution in code.

So in order to introduce this concept more clearly, let's make an app! This may not always hold true, but I am going to suggest that the first step to writing an app is having an idea. So let's decide on an idea. I want to further enforce the importance of the last two posts about IBOutlets and IBActions. Let's make an app where we have a label that displays a number. We will also have another label that displays a different message based on the number that is displayed. And then we will have a button that we will press in order to increment the value of the number label which will in turn change the message label.

What do you think? Sound pretty awesome? I'd say it is a great next step. So if you think about it, what's next? What type of logic do we need to come up with in order to accomplish this simple task? 

Before we write one line of code, we need to have a firm understanding of what we want to do. This results in much more efficient app development. Plan and think first and then make it happen. So let's talk about this. We know that with an IBAction, we can hook up a button to run a specific bit of code. Ok, once we have that happening, we need to make sure that the code that is run makes the value of the label change. But what does it need to change to? How do we know what the label's value is? How do we know what to change it to? How do we make sure that we are just incrementing it by one?

These are all problems we need to solve. We need to make sure that the logic we put into our app can handle all of the different scenarios we can see it needing to handle in order to be the app that we set out to design it to be.

Before we get too far into the nitty-gritty, let's see if you can lay the foundation of our app on your own. Based on the specs of the app I described, you'll need a button, two labels, and a way to have those all play nice together. Go ahead and try setting everything up! Hint: remember that IB is your friend!

Bonus question: How will we handle keeping track of the value of the label we are incrementing?

We're going to cover the actual logic we need in the next post, but I really want you to review what we have learned so far by taking on this little challenge.