Ghostboard pixel

The Most Common Mistakes In iOS Development

The Most Common Mistakes In iOS Development

Recently I’ve published a post about the most common mistake in using UITableViews. The post has become quiet popular, so that I’ve decided to write this post about the most common mistakes in iOS development. I hope it will help some developers to avoid some pitfalls.

Hint: This post has been updated to Swift 3

 Massive ViewControllers

The Model-View-Controller Pattern (MVC) is very common in iOS development. The idea is, that there are basically three layers:

  • The model layer is the data and business logic layer. This layer shouldn’t talk to the view layer directly.
  • The view layer consists of the objects that build the user interface. Good examples for this are UIButton, UITableView and UILabel. The view layer is not allowed to speak to the model layer and it should not have any business logic.
  • The controller layer stands in between the model and view layer. Since the model and view layer are not allowed to speak to each other, it is the job of the controller layer to let the model and view layer work together.

However, in reality the controller layer much more than it should do. Very often a lot of business logic and stuff that the view should do can be found in view controllers. As a result, view controllers tend to become very massive. This is a bad software design. So it’s very important to bear this in mind.

For more details you can take a look at the post “The MVC-Trap“.

UI operations besides the main thread

If you are encountering very weird bugs that are difficult to reproduce, it is very likely that there is a multithreading problem in your app. In fact, UIKit is not thread safe. Most developers know about this, but it still happens very often that UI stuff is done offside the main thread because it’s easy to forget to jump back to the main thread. So be careful, if you are executing concurrent code. For more details about concurrency take a look at the post “A Simpe NSBlockOperation Example”.

Testing only on the simulator

The iOS simulator is very fast and highly usable. By using the iOS simulator you can speed up your development and it’s much easier to access the file system of your app. However, the iOS simulator is not a real device so that there are situations where device and simulator behave differently. And the iOS simulator has much more performance than a real device, so that the simulator is not the perfect choice to test the performance of your app.

So you should not only use the simulator but also a real device at development time. Fore more details take a look at the post “Simulator vs Real Device”.

Testing only on the newest device

So it’s a good idea to use not only the simulator but also a real device. However, that’s not all. It’s also not a good idea to test just on the newest and quickest device. Imagine you are developing an iPad application and you are testing just on the iPad Pro. But you have to consider that iOS 9 still supports the iPad 2 and that the performance of the iPad Pro is much better than the performance of the iPad 2. So it could happen that your app behaves very good on the iPad Pro but very bad on the iPad 2. Of course you don’t have always all devices, but you should bear that in mind. And, if you have several devices, you shouldn’t use just the newest one.

For more details take a look at the post “What Is The Best Test Device At Development Time?“.

Not caring about memory usage

It’s true that the compiler and iOS does most of the memory handling for you. However, this doesn’t mean that you shouldn’t care at all about memory usage. It’s still possible to have memory leaks. This could happen due to so-called retain cycles. Especially if you are using delegates this could happen very quickly. So you should pay attention to this issue. Additionally, you should also consider the memory usage of your app. You can do this either in instruments or in the “debug navigator” tab in Xcode:


For more details take a look at the posts “Building Memory Efficient Apps” and “Swift: weak and unowned”.

Force Unwrapping Optionals

One of the main purposes of Swift is to create very safe code. One integral part to achieve this are optionals: Non-optional values have to have a value and must not become nil. So if you want a value to have the possibility to become nil, you have to declare the value as an optional:

var anOptional: Int? = 5

Now if you want the optional to interact with non-optional values, there will be a compiler error:

var anOptional: Int? = 5

var anotherIntValue = 8

anotherIntValue = anOptional //COMPILER ERROR!

So you have to unwrap the optional value:

var anOptional: Int? = 5

var anotherIntValue = 8

anotherIntValue = anOptional!

However, this is a forced unwrapping and this should only be done, if you are very sure that the value is not nil. If it is though, the program will crash. So in almost all cases you should do it in a different way, for example by using optional binding:

var anOptional: Int? = 5

var anotherIntValue = 8

if let anOptional = anOptional {
    anotherIntValue = anOptional

Alternatively, you could also use guard.

For more details take a look at the post “Optionals in Swift”.

Not staying up-to-date

iOS development is changing very quickly. Every year the platform has new inventions and that is of course reflected in the development tools as well. So there is no point where an iOS developer knows enough. Instead, he has to learn on a regular basis in order to stay up-to-date. There are several ways to do so: For example, you could read blogs, listen to podcasts or watch video courses. Books are still a very good way to learn things and there are a lot of very good iOS development books out there. Here just a small list to give you an impression:

I’ve published a post about the best iOS development resources, so take a look at it, if you need some inspiration: How To Stay Up-To-Date On iOS Development.

You can also check out the latest issue of my iOS dev newsletter.

Wrong UITableViewCell reuse

Last but not least I wanna mention the UITableView cell recycling pitfall. UITableView is a very important component that is used in almost every iOS app. It also has very good performance. It achieves this by recycling cells, that means that cells are reused when the user is scrolling. This way new cells don’t have to be created, which would have a bigger performance cost. However, if not all properties are reseted correctly, weird things can happen. Take a look at his post for more details: “The Most Common Mistake In Using UITableViews”.


Title Image: @ schatzy /