Browsing Q&A websites I often find people having problems when learning iOS development through tutorials:
“I just don’t know how to make my own code. I can go through these tutorials and write their code and understand, I just don’t know how to implement it all by myself.”
This is understandable. Authors suppose their tutorial will introduce you to a topic, but all they do is to show you something without giving you the understanding of what you are doing. In the end you are only copying someone else’s code.
I think developers have a big flaw: they forget how hard it was for them at the beginning. After years of experience, they know and understand what they are doing, so they assume it should be easy for everybody else as well. This is why so much material out there is in the form of tutorials. Some developers assume you will be able to pick concepts just by seeing a specific application of such concepts.
You rarely can, though. Tutorials usually leave the reader knowing only how to do some very specific things. But without understanding what goes behind something you learn, you will be unable to write your own app. The moment you deviate from the specific example in the tutorial, you are lost.
Maybe some people find it easy to learn this way. I do not and from the comments I see, many others do not either. Even if you do manage to extract knowledge only from examples, I do not think that going through countless tutorials is the best way to learn how to make iOS apps. If I look back at the start of my programming career in high school, I had the same problem. Most of programming was taught to me by examples. My teacher that was too lost in his own world to actually care that people understood what he was teaching. As a result I could not do much except copy some code and try to modify it to achieve what I wanted. You can imagine that I did not accomplish much. I did not even know what loops were for.
I once took a book from the school library which showed how to make many different cool 3D graphs. I copied the code and then showed my friends, but I could not really claim the result as mine. I had no idea what was written in those programs program and how to achieve a similar result myself. When they asked “how did you do it?” all I could reply was “I copied it from a book”.
It was only in university that I finally got good programming courses that made me understand how things worked and enabled me to start programming.
Still, most of the material I find around the web these days, either free or paid, is in the form of tutorials that do not give you enough understanding of a topic. This leaves me puzzled. I understand the “show, do not tell” approach, but you have to show enough for it to be valuable.
Many people come to iOS development and they do not know where to start. There is a lot of material and it is easy to get lost. When I started I had the same problem myself. iOS development is a vast field, but when you look at how most iOS apps are developed, there are only a few fundamental concepts you need to know. Whatever kind of app you are developing, these concepts will be at its foundation (games might be an exception, but some of them are often built using these concepts and technologies).
So, if want to learn iOS development and you do not know where to start, this are the fundamentals I think you need to understand. When you know these, you will be able to develop many different kinds of apps, and you will be able to expand your knowledge as needed.
I am also in the process of creating a course on these concepts. If you are interested, make sure to subscribe to my mailing list at the bottom of this post.
The MVC pattern and view controllers
At the core of every iOS app stands the Model-View-Controller pattern. As the name suggests, this pattern is composed by three layers.
- The model encapsulated the data and the logic of the app. The classes in the model are concerned about the representation and storage of the data and the operations on. They are not concerned about the representation of such data, nor they are about interface of the app.
- The view layer is responsible to present and format the data for the user. It allows interaction, to enable the user to manipulate and edit the data. Views tend to be reusable. In iOS you can find many standard views like labels, buttons, etc. The view layer should not be concerned about the storage of data.
- The controller layer is responsible of mediating between the other two. Controllers connect the views to the data and are also responsible for setup, coordinating tasks and interpreting user input in the app specific way. They are usually the least reusable part of an app (although they can still be).
One common misconception about the MVC pattern in iOS is that these three roles are separated and any given class should fit perfectly inside one of them. This is not true and in often the boundaries blur.
On one side of the spectrum we can have model controllers. While a model class is usually concerned only about data representation and manipulation, a model controller can be responsible, for example, of storing the data on disk or transmitting it over the network.
On the other side of the spectrum we have view controllers, who have a central role in iOS. A view controller usually manages a single screen of an app. View controller in iOS have an associated view, which usually represents a screen and contains all other views for that screen. View controllers in iOS also manage autorotation and perform resource management, receiving memory warnings from the OS when the memory starts to fill up. Since they represent usually one screen, the flow of the app is usually defined through the transitions from one view controller to the other.
A common misconception surrounds view controllers: many developers think that they should be the only kind of controller present in an iOS app. The opposite is actually true. You often need other type of controllers in any non trivial app, often including model controllers.
This misconception makes it so that a lot of code gets written inside view controllers, making them huge monoliths that are impossible to reuse. Keep in mind that view controllers are still controllers and they should only be mediating between the model and the views. Since they are leaning more on the view side of the pattern, much of the app logic should be contained in the model or in other model controllers instead.
View controllers often also take care of the user interface, which should instead be handled by the view layer. You can read more about the central role of view controllers in the MVC pattern here.
The view hierarchy
The user interface is managed by the view layer of the MVC pattern. Views occupy a rectangular space on the screen. Some of them might seem to have a different shape, but that’s an illusion accomplished through transparency. The surface of a view is always rectangular. This rectangle is placed on the screen according to a coordinate system. Luckily it is less and less needed to alter coordinates directly thanks to technologies like Auto Layout. I have a full, in-depth article on Auto Layout in iOS, but here is a summary.
Views are usually contained into other views, forming a hierarchy. At the top of this hierarchy sits the window, which is a special kind of view. Views associated to view controllers are usually added to the window, but you rarely have to worry about this, since this is accomplished through containers. What you usually worry about is only to lay down the user interfaces for each view controller and specify how to transition between them.
UI work is done through a visual editor contained in Xcode called interface builder. iOS offers a lot of standard views you can assemble to create rich interfaces. It includes simple views like buttons, labels, images, switches, sliders, date and list pickers, but also more complex ones like scroll views, web views, table views and collection views. You can of course build your own custom views, but many things can be done by assembling and customizing standard views.
All these views are available in Interface Builder as drag and drop elements to allow the developer to build the UI in a visual manner. Some developers prefer to do everything in code, but I am personally against this. The UI in Interface Builder is easier to visualize and to modify and I never find compelling reasons to create the interface from code. Granted, some things are not possible in Interface Builder, so they need to be done in code. For the rest, I do not find the reasons so strong to give up the convenience of a visual representation. Keep in mind that one way or the other, you might be fighting against part of the community that does it the other way. In the end it’s always better to agree to a standard for the project you are working on. Also, interface files might give you problems when multiple people on a project work on them. I personally still prefer to use Interface Builder whenever possible, though.
Containers and Storyboards
View controllers manage a single screen of the app, but non trivial apps usually have more than one screen. You need a way to move from one screen to the other (which means from one view controller to the other). This is usually done through container view controllers. They are special view controllers that are responsible to manage a list of view controllers and transition from one to the next.
- The navigation controllers is, I think, the most common container view controller used on the iPhone. It makes it possible to structure view controllers in a hierarchy and to navigate through them through the right to left transition we all know. The Settings app on the iPhone uses a navigation controller.
- The tab controller is also quite common. It displays a tab bar at the bottom of the screen where you can tap to reach any section of the app. The clock app on the iPhone and the iPad uses a tab controller.
- A page view controller offers the option to move between different screens as they were the pages of a book. It even offer a page curl animation if you want. The iBooks app on the iPad uses a page view controller.
- The split view controller allows you to place two view controllers next to each other on the screen. The master view controller on the left controls the content of the detail view controller on the right. This was available only on the iPad for a long time, but is now available also on the iPhone since the introduction of bigger screen sizes. The Settings app on the iPad uses a split view controller.
These controllers can be combined to create more complex navigation structures in your app. For example, navigation controllers are often inserted inside tab view controllers. In this way you can manage each section of the app hierarchical way, independently of other sections.
It is of course possible to write your own container view controller and Apple offers some documentation if you want to do so. I would advise against it though. The main reason to write a new kind of container is usually because developers want to have different kind of transitions between screens, other than the standard ones offered by iOS. Writing a container view controller is easy to get wrong, though. A container is responsible to manage the life cycle of the contained view controllers, adding and removing them as children and make sure that the right lifecycle methods are called at the right time. Some times it might seem you got it right, to only get hard to find bugs later.
If you want to have custom transitions between screens it’s still possible to use a standard view controller container and to customize its transitions. In 99% of cases (100%, even?) a navigation controller or a tab controller with custom transitions will be enough to satisfy your needs. Avoid to write all the code a custom container needs, if you can.
The flow of screens of your app and the transitions between them can be laid out visually in Interface Builder too, using storyboards. Storyboards allow you to lay out all the view controllers of your app in a single file and connect them through segues that specify how you move from one to another. In this way you can have an eagle eye view of your whole app and see which screens are reachable and from where. This is useful especially when you are inspecting an app (or a part) you didn’t write yourself. Figuring this out from the code is a really tedious job. I know, because I started developing for iOS when storyboards did not exist yet. When a project grows in size, a single storyboard might become too big to contain all the flow of your app, but you can split it into multiple storyboards (it is not a requirement to have only one storyboard per project).
You can find more about storyboards and segues in Apple’s guide on view controllers
Table views and the delegate pattern
Table views allow you to display a scrollable list of items on the screen. This is such a common task that table views make their way into many iOS apps in one form or another. The main confusion on table views at the beginning comes from an assumption many developers make about how they should work. If you never used a table view before, you would think that you should pass your list of objects to the table view and the table view will display it on screen.
Table views work in a sort of reversed way. A table view makes use of another common iOS design pattern: the delegate pattern. In the delegate pattern, an object gets configured by an external one, called the delegate. The delegate, though, does not configure the other object in an active way, but mostly in a passive way. When the configured object needs some information, it asks for it to the delegate. Moreover, the delegate can receive messages when some event in the configured object happens. In this way, the original object can ignore external implementations and be more generic and reusable. Table views are not the only iOS class to use this pattern. Others, like scroll views or text fields for example, do as well.
This is how a table view works in iOS. You need to assign to a table view two delegate objects. one is called the delegate and the other one is called the data source. The data source is the only needed one of the two and passes the data to the table view. It has two required methods: one to tell the table view the number of items in the list and another to pass these items to the table view when it requests it (a table view asks only for what fits on the screen at a given moment, to better manage resources). The delegate manages the appearance of the table view, as well selection, deletion and reordering of elements.
All the rest
Is this all there is to iOS development? No, Of course not. The SDK includes libraries many more libraries to manage networking, animations, storage of objects, the various device sensors and many more. All these are useful and needed for specific kinds of app. But the above concepts are at the core of any app you will develop. If you miss them you are going to find your way through iOS development much harder and you will end writing your apps in a suboptimal way at best, or an unmanageable one in the worst case.