In the past few years I've seen lots of good & bad projects. In most of the cases developers made the same issues, in this post I'm trying to give you some tips about how NOT to code (iOS) apps.

1. Do NOT drop every file into the root folder

Use folders to represent groups in Xcode. You know like in real life, you don't throw all your clothes into the shelf, right?. :) Be well organized this is the only way to create a good project. You know in Xcode 9 folders will be created for your groups so don't hesitate, it's time to learn some conventions, don't worry here are my Xcode conventions to get some inspiration.

2. NEVER leave warnings in your project

Always fix every single warning! There is a reason that warnings exists, but you should never leave any of them in your production code. If you want to be more radical, there is a build flag in Xcode to treat warnings as errors. TURN IT ON! Kill all warnings!

3. Do NOT let your code to grow on you

You know that awkward situation, when you open a source file, and you start scrolling, scrolling and you have to do even more scrolling. Yep, it's usually a massive view controller and in your mind you already know that you are lost forever. Good advice: use SwiftLint, because it can generate a warning - see previous point - if your source files grow too big. Also you should read my preivous article if you are fighting against massive view controllers.

4. NEVER write more code than you need

NEVER IF RETURN + ELSE: You know, when you return something in an if block you don't need an else pair. Simply just return after the if like this:

if something {
    return true
return false

NOTE: This is just my personal preference, nothing bad happens if you write the else pair, but why would you write more than you need, right?

The other thing about this tip is that I've seen projects with spaghetti codebase. Yes, that ugly one. Some of the developers don't even know how functions work, they just copy paste & change a few things. That's ridiculous. Think throgh the things that you have to solve and NEVER COPY THE SAME CODE TO MULTIPLE PLACES. Create new functions if you need and use them in the proper way.

5. Do NOT reinvent the wheel

If there is a best practice, use that. You should ALWAYS google the problem before you start coding. You should ALWAYS think through the problem before you start coding. Remember: you are not alone with your coding issues, I can almost guarantee that someone already had the exact same issue that you are working on. StackOverflow is the right place to look for solutions. Use the power of the community, don't be afraid to ask questions on the internet, or from your co-workers, but don't expect that others will solve your problem, that's your job.

6. NEVER connect 3rd-party libs by hand

Please ALWAYS use a dependency manager, like CocoaPods, Carthage or Swift Package Manager. NEVER add your dependencies manually into Xcode. I've seen projects where some dependencies were added through CocoaPods, but Google Analytics was wired in by hand, it's UGLY.

7. Do NOT use too many dependencies

If there is a "native" solution, use that. Consider the following example: you have to download a single JSON document from the web. What would you do? Use a few lines of code including some "native" NSURLSession object OR add the whole Alamofire framework to your project which contains a lot more functionality as well, but you won't need anything else from the library EVER. Please take my advice: Do NOT use 3rd-party libaries for trivial tasks, but only for complex issues (like the next one).

8. Do NOT try to write async code without promises, operations or 3rd-party libs

Look, if you know what is the "Great" Pyramid of Doom, you'll know what I'm talking about. You're going to write async code eventually, most of the API's have async methods. Even a simple networking task is asynchrounous. Before you make a HUGE MISTAKE, consider reading my article about error handling & promises.

Promises are high level abstractions over async tasks, they'll make your life SO MUCH BETTER. You can go with NSOperation tasks as well, but if you'd like to have some syntax sugar I'd recommend Promises. My only problem is that if you have to pass data between operations you'll have to create a new operation to do it, but in exchange of this little inconvenience they can run on queues, they can have priorities and dependencies.

9. Only use singletons if necessary

They are the root of all evil. Honestly, avoid singletons as much as you can. If you want to deal with mixed-up states & untestable code, just go with them, but your life will be better if you take my advice. If you don't know how to avoid the singleton pattern please do some research. There are lots of great articles on the net about this topic.

10. NEVER create helpers (or managers)

If you need a helper class, you are doing things WRONG! Every single object has it's own place in your codebase, helpers are useless & not good for anything. Rethink, redefine, refactor if you need, but avoid helper classes at all cost. Learn about Swift design patterns or draw a chart about your models, but trust me there is NO PLACE for helpers in your code.

+1. Side effects

There are two great articles about functional programming & side effects, please read them carefully, and NEVER ever make the same mistakes: link 1, link 2