Hiring an iOS developer (or any software developer) can be a daunting task. Usually when a company feels the need to hire a developer, they should already be actively looking for candidates and, more often than not, haven't started doing that. Perhaps one of the core developers has just left the company and management starts desperately seeking a replacement, or the product is finally gaining traction and the team is just spread too thin and starts falling behind on the schedule. Either way, this need for another hire is already being felt and the company hasn't even stated looking for candidates.
The search begins
Getting to a single hire is the process of filtering the pool of candidates over and over until a single candidate remains. Some of these filters are, of course, what we can call hard filters. How big is your selection pool to begin with? Can you afford the hire? Is your company attractive enough for the hire? Do you share the same values? Do you require that your employees be physically present at the office? There is much competition nowadays over talented software developers and things can get dire if you are in one of two extremes: somewhere with a lot of competition (e.g. Silicon Valley), or somewhere that does not attract much technical talent. This is partially why we keep hearing more and more about remote first companies.
The whole idea of focusing first on the hard filters is to not waste anyone's time. Neither yours nor the candidate's. Figuring out these hard filters will help you set your expectations.
The selection process
There's much debate of how to effectively conduct the interviewing process of software developers. The industry standard and omnipresent whiteboard coding interview is being put into question. Whiteboard interview might actually make sense if you are hiring a college professor. Even if your candidate enjoys solving puzzles on a whiteboard, you should be testing him for something that will actually resemble the work he will be doing in the company.
Enter the coding challenge
Back when we were hiring a senior iOS engineer at Hole19, we were getting a lot of noise. Most of the candidates we interviewed could not be considered senior software developers and we were wasting a lot of time interviewing people while also getting an important release done. After it became clear that simply filtering candidates by their Github and Linkedin profiles was not accomplishing much, we devised a simple coding challenge that each potential candidate could complete at their own pace.
The challenge was designed to resemble everyday tasks of the iOS engineers at Hole19. We had a spec describing the desired functionalities and some UI mockups. The candidate was to consume an open REST API and present items on a list. A tap on each item would take the user to a detail view. There was also a simple search view.
There were few technical constraints for the challenge. The candidate had to write code in Swift (since we were writing Swift since it was released in 2014), and they were also supposed to write some tests for the project. All the challenge did was to show us how well the candidate handled common tasks of an iOS engineer without forcing them to use a specific framework that they might not be familiar with (we actually learned about some cool frameworks when reviewing the challenges). We also let out a few details on the spec to see what the candidate would do without explicit direction.
After the first batch of coding challenges arrived for me to review, it was clear that it was doing what it was supposed to do. Most of them, maybe something around 80%, had no tests at all even though that was explicitly written on our specs, others would on the first seconds of interaction.
By far, the most common problems found on the challenge implementations that were being sent back to us were all related to cell reuse. These kinds of problems should be familiar to every iOS engineer out there and they will still bite us from time to time. Not even the big guys are immune to that. Another common problem is that iOS engineers are notoriously bad at testing. In most of the tests that I saw, the candidate was actually testing the response of a remote API and not the code that they wrote.
When the time came that we had to interview the few candidates that had successfully passed the coding challenge stage, we were fairly convinced that they could actually code. It was now a question of seeing just how much the candidate knew about the platform they were working on and how they would deal when confronted with different ideas and opinions.
The interview was usually done via Skype calls as we were interviewing people from all over the world. I would usually interview the candidates alongside with João Costa who is the engineer with most time at the company so we could avoid any kind of bias. For the technical side of the interview, I came up with a list of 20 questions to ask the candidates. I rarely asked all the questions though. The idea was not to find someone who could answer correctly all 20 questions. Some questions were open ended and didn't have a correct answer. Others were designed to be follow ups to previous versions. If a candidate said he has no previous experience with CoreData, it really makes no sense to ask him how to set it up with a private queue to be able to support concurrency. I would, if possible, introduce the questions during out conversation as I feel a little bit awkward pretending I am a trivia show host asking questions.
Some questions had a straight answers (e.g. "on what thread is a NSNotification received?"), others had more elaborate answers (e.g. "when does it make more sense to post a notification instead of defining a delegate to your class?". Very few people could answer cardinality right away). Other questions were supposed to make the candidate state an opinion and defend it: "What are some of the ways we can build an UI for an iOS app?". Even though I have a very strong opinion about that, I was interested in hearing the reasoning of the candidate and how well would respond to someone with a different opinion on the subject.
The truly open ended question had really no answer and were just to get the candidate talking and evaluate how well he knew what he was talking about. "What is your favourite feature of Swift?" A candidate can answer pretty much anything he'd like: no need for semicolons, writing func is easier than writing function, optional type, protocol oriented programming. The only bad answer I heard for this question was: "I hate Swift and I can do anything you do in Swift in Objective-C" (the same candidate told me that the UICollectionView was useless and he could do everything with a UITableView. When I asked him about layout, specifically about something simple like adding spacing between the cells, he told me that the best way was to add rows with empty and transparent cells).
We never expected someone to actually be able to answer all the questions we asked. "I don't know" is in many cases a perfectly accepted answer. After all, we are constantly introduced to new features, new frameworks and new concepts. In some questions we guided the candidate towards the correct answer and sometimes this is much more useful to evaluate someone's skills than having an answer straight away.
After the tech interview we knew of sure if the candidate was or was not what we wanted. Not only we evaluated the technical aspect but also his soft skills. How well did he communicate? What was his attitude like?
The last step of our interview process was a chat with our CEO to discuss thing like company values and vision and finally get to offer.
Though I do not claim that our hiring process was impeccable, I was quite proud of it. Not only we got to someone that we felt sure was the person we were looking for but we also avoided the common pitfalls of software interviewing. What was also great, was to get feedback from the rejected candidates telling us that this had been the best interview process they ever had and even keeping in touch with some of these people. They were not what we were looking for at the time but they might be what we are looking for in 6 months from now. Some of them were really strong candidates and were not hired only because we had only one opening and the chosen candidate had a bit more of experience.
I am sure that because we took the time to treat all our candidates really well and tell each one of them exactly why they were rejected will not only help them to become better engineers but will also make it easier for us to hire in the future as some these rejected candidates will be the first people we are going to talk to when we open up a new position.