Being iOS Software Engineer is awesome – it’s fun, it’s challenging and it (in some cases) allows you to be creative. Apart from that, iOS engineers are one of the most wanted engineers on the job market. Having in mind all the different devices that Apple has (and will have), this trend will surely continue in the future. If you are iOS engineer yourself, you’ve probably felt that by the number of job offers you receive. But, it’s not only the demand for iOS developers huge – there are a lot of iOS engineers too. Although it’s not possible to count all the ones out there, this might give an indication.
This indicates that finding a great iOS engineer might be like finding a needle in a haystack.
Why do you need a great one anyway? An average one can probably finish the job as well, and they will cost a lot less to hire. But thinking long term, the reverse is true – architectural mistakes, careless coding, coupling, spaghetti code, concurrency bugs that appear once in 1000 times and other common developers’ mistakes will introduce lot more costs and quality issues in the future. And having a low quality app might be a deal breaker for businesses.
That said, how do you find a rock-star engineer? What traits and characteristics should they have so they can be recognized? In this post, I will try to point out the key qualities that, in my opinion, are crucial for any iOS engineer to master. Of course, this will be just rough outline and not everyone can know everything.
We start with the basics – one has to be an excellent software engineer first and iOS platform specialist afterwards. This means that a strong computer science background is mandatory, like knowledge of the basic data structures (arrays, hashes, trees, graphs, stacks, queues etc.) and algorithms (sorting, searching, recursion, dynamic programming etc.). Big tech companies like Facebook, Google, Apple and Microsoft are all first evaluating these things before going on with the platform knowledge questions in their interviews. One might ask why everyone tests these skills if they are rarely used in the regular development? Well, first, how you approach the algorithmic problems gives a very strong indication about your thought process. With that same approach you will tackle the problems in your everyday work and if this thought process is not clear, efficient and creative, then this is a serious red flag in your competence as an engineer. Second, poor algorithm design in your everyday work might slow your apps down a lot, especially when you have millions of users. Third, with deep knowledge of the data structures available, you can design your solutions more elegantly. For example, imagine you have to design a new social network. If you don’t know about graphs, it will be much more complicated to implement all the path finding algorithms that most social networks have.
Of course, being in the industry and not using algorithms that much can make you a bit rusty. Revising them from time to time can be really beneficial for you, not just if you want to interview for a new job, but also if you want to produce better work in your current position. Luckily, there are some great websites for algorithmic problems, like HackerRank, TopCoder and Codility. Apart from the interesting tasks, they offer also reading material which is useful for solving them. On top of that, they are competitive and might become addictive. If you want to dive deeper, there are also really good classic books on the topic, like The Algorithm Design Manual and Introduction to Algorithms.
Software engineering principles
Another really important skill set are the software engineering principles. This might not be something that one can learn at college like the algorithms and data structures, it’s mostly mastered by working in a good software development company. I say good, because not every company follows them – it might be cheaper and faster to develop something with lower quality – a false advantage over the other software manufacturers that will probably backfire in the future.
What are those principles? First, let’s start with writing clean, robust and bug-free code. There are many books and articles on this matter, with Clean Code being one of the best ones. In a nutshell, the most important characteristics of your code should be:
– it has small, well defined functions that do one thing
– same code should not be repeated (the DRY principle)
– code must be well identated and the identation style should be the same throughout the codebase
– there has to be a clear separation of concerns
– code should be nicely structured, code doesn’t go with spaghetti
– and much more…
Testing and CI
After the quality code is written, it has to be tested (actually some like to do the tests before writing the code). Having smartly written unit tests can provide enormous contribution to the quality and stability of a software. It gives you the bases for future refactorings and improvements and can catch some edge case bugs in the code. On iOS, having solid code coverage can be a challenge, since it’s pretty hard to test view controllers. To address this, different architectural patterns are used, like MVVM, dependency injection, VIPER, mocks etc. In any case, writting more functional, pure functions make testing a lot easier. One book that you might want to check is Test Driven iOS Development.
Apart from the unit tests, one can also write UI tests. While the unit tests are definitely needed for most iOS projects, the usage of UI tests depends mostly on what kind of app you have. They are really handy for apps with many screens and features – especially if you do frequent store releases. It would be really time consuming if you test every screen of the app every time you do an update. For example, Facebook is committed to making app updates every two weeks – and UI tests are perfect for this fast and agile development cycles. Or if you have one core codebase and you make branded clones out of it for different clients, the more clients you have, the bigger the need for automated testing.
On the other hand, UI tests are still hard to write, they can consume a lot of time for maintenance. If the app is in development and the UI is frequently changing with different iterations, having UI tests can be a nightmare. It all boils down to you being great engineer who can tell whether this kind of testing is needed or not in your project.
When you have tests, you also need to have automatic execution of them on every commit (we haven’t mentioned version control systems so far, but that’s so basic and required for anyone who writes software that we will not cover it in this post). For this, continuous integration should be used, in order to avoid integration nightmares when you have multiple developers working on the same project. There are many CI systems out there, like Jenkins and Travis. Having automatic execution on every version of your software provides opportunities to track the status of the build (who broke it and needs to fix it), track the code coverage, perform static code analysis and create snapshots releases of your current state of the project. For static code analysis, there are Sonar plugins for Objective-C and Swift that you should use. For iOS, it’s also useful to detect memory issues in your code. For this, Facebook has some excellent tools.
Usually in our work, we are integrating some third party code, which we don’t want to copy in our project whenever we need to update to newer version. For this to work, we need dependency management system. On iOS, the two most popular ones are CocoaPods and Carthage, while also you should keep an eye on Swift Package Manager in the future.
When you are developing a feature, the chances are that someone has already developed something similar and has already felt the consequences of the good/bad design decisions made during the process. In order not to make the same mistakes to common problems, the concept of design patterns was introduced by the Gang of Four, in their classic book. It’s really important to be aware of the existence of these patterns, you shouldn’t re-invent the wheel on every problem you encounter – that’s not very efficient. The more experience you gather, the more confident you get about picking/not picking a design pattern for the problem at hand.
Having a good organization and overview of the work that needs to be done is as important as the technical stuff above. Working in agile development cycles like Scrum, where the work is split in sprints is something that every good engineer should embrace. Also tools like JIRA and Trello (basically now they are under the same company) are quite handy. These tools also support versioning, which is really important for tracking the state of your released artifacts, especially when you are doing frequent releases.
So far, we’ve covered the skills needed for any great software engineer, no matter the technology. Stay tuned for the next post, where we will cover the iOS platform specific knowledge which I believe is fundamental for anyone who does iOS development.