A little while back, I was asked to put together a small pair programming exercise for iOS candidates to work through during an interview to help highlight and demonstrate their skill set in relation to the tools and concepts used in my company’s iOS application. I thought it might be interesting to re-hash my though process and steps as I worked through (and re-worked) the process of putting it all together.
Our app pretty much exclusively gets its data by consuming JSON from our API, so I needed to build the exercise based off of connecting to endpoints and processing their JSON responses. If you’ve read some of my other blog posts, I’m fond of using The Movie Database API due to its verbose documentation, as well as its ease of authentication. All you need to do is register for an account and you’ll get a unique API key that you simply pass along as a parameter to each of your requests. Our app also doesn’t use too many third party libraries, so I wanted to limit the toolset to (mostly) using built-in Apple libraries, or as least using any outside packages as minimally as possible. Also, I had to figure out a way to timebox what I would be working on with the candidate to one hour (the average length of the interviews).
Without going into a ton of detail, some of the concepts and tools my company’s app used which I wanted to incorporate into the interview exercise are as follows:
- The majority of the app is written in Objective-C
- Programmatic views
- Constraints by way of the Visual Formatting Language
- Newer features and classes were being written in Swift
Taken directly from the README in the repo, I put together these requirements:
- List movie categories as a
UITabBar, with the following categories:
- Display results for each list in a
- In each table cell, display the
posterPathof the movie
- Load the
- Add at least one unit test, written in Swift
Also for clarity, I added these additional specs to give a complete overview of the app
- Language: Objective-C (Swift for unit tests)
- Minimum supported iOS version: 10.0
- Orientation support: Portrait only
- Device support: iPhone only
- Localizations: Not needed
- Dependencies (app is slightly structured toward these packages, however everything can be built with native-only APIs or dependencies of your choice):
- Dependency management: CocoaPods (can change to your choice)
While I originally was debating on whether to have the candidate start the interview with a bare bones skeleton or not, I quickly realized that the time allowed would need me to restrict the pairing portion of the interview to key areas where the candidate would fill in missing portions of code, or perhaps build out very simple classes. You can see for yourself in the repo what those areas were, but I tried to make them as general as possible so as to not force him or her to write the code exactly how I had, but instead still achieve the same result with their own direction.
Additionally, I felt the dependencies I chose provided enough support during the interview that the interviewee would not get caught up in the tedious nitty-gritty of some of the setup, but instead could focus on the high-level feature set to demonstrate their skills. As a bonus, I could see how they dissected third-party code and documentation for the information they would need to utilize these packages.
I won’t cover every detail of developing the coding exercise, though I’d like to go over some of the highlights of putting together the features that make up the codebase, some of the decisions I made, and the process of “fleshing them out”.
Movie list categories
One of the first things to note for each of the movie list categories (Now Playing, Popular, Top Rated, and Upcoming) is that the tab name, header title and API endpoint all use the same text, albeit it different formats. The tab and header use a title format whereas the endpoints use snake case for proper URL formatting.
For simplicity’s sake, I hard-coded the endpoints to a lazily-instantiated property
I also created a method to titleize a passed in endpoint
Finally, I combined the property and method to build the
with the appropriate endpoint and title
In order to simplify the process of deserializing the JSON coming back from the API, I decided to use the JSONModel CocoaPod so as to not bog down the candidate with tedious JSON deserialization. Although this could be a good exercise in seeing how the candidate handles JSON HTTP responses, in this case there were more important concepts to focus on. I figured it would give me a glimpse in seeing how the candidate seeks out documentation for the library, as they were tasked with adding the properties to the model, as well as telling JSONModel to map the JSON keys from snake case to camel case when deserializing.
This was one of the most interesting challeges to work through with a candidate. While most iOS engineers are very comfortable in handling asynchronous behavior with callbacks, promises, though similar, still take a bit of getting used to. The fact that you can chain promises, rather than have a series of nested callbacks, takes a bit of practice for building and implementing. As a result though, I believe promises can make for much cleaner code.
My company’s application was written using a homegrown implementation of promises. In the case of the pairing challenge however, I decided to go with PromiseKit as it both allows the candidate to not concern themselves with the internals of a custom construct, but may also hasten the process if he or she has ever used the third-party library, not to mention PromiseKit’s thorough documentation.
I started off with defining private property and method definitions in the implementation file.
My company’s app implemented the API client by instanting it once and passing it around controllers where needed, so I followed the same pattern.
Since each endpoint followed the same format, only one public method was needed,
fetchMovieList, in which the movie list category type was passed in
and a promise of type
AnyPromise was returned.
NSURLRequest was constructed and returned from
requestForMovieListWithType, which would take in the
listType string, and interpolate the
Now, if the request was executed, the app would crash with this message:
This error would guide the interviewee to notice
PromiseKit was complaining that the request was being executed on the main thread. Through some discussion and/or
possible documentation reading, he or she would come to the conclusion they would need to instantiate a new
NSOperationQueue for the
The code challenge app only consisted of two programmatic views, a
LoadingView and a custom
LoadingView was provided in full, for both the interviewee to focus on more important topics, as well as to
potentially be used as a guide for “fleshing out” the needed parts of the
doesn’t really handle any sort of special configuration, but a couple of items just to showcase are:
- Interpolating the
POSTER_BASE_URLand rendering it asynchronously
- Lazily-instantiated UI properties, which was a pattern I mimicked throughout the exercise to reflect the app the candidate would be working on when hired. However, the starting point only defined the properties, and the interviewee could instantiate them however he or she wanted.
- Using Visual Formatting Language for constrants. Again, not a requirement, but encouraged to test the potential hire’s skillset.
Unit Testing and Swift
Because all work going forward on my company’s app was in Swift, the candidate should have at least a basic knowledge of it. I figured I could “kill two birds with one stone” by having him or her write at least one unit test in Swift. Unit and UI tests are something I feel I don’t see enough of in iOS applications, so I wanted to see how comfortable the iOS engineer was in writing them, as it would be something strongly encouraged for each new feature and bug fix.
Adding Swift into the mix could also show me how the candidate handled Swift integration in an Objective-C project, considering he or she would need to create a bridging header and
translate initialization syntax from an Objective-C class to a new instance declaration in Swift, depending on what the interviewee wanted to test. For my test, I simply verified
the return value of the
fetchMovieList method in the
MovieClient class was indeed of type
Putting together a code pairing exercise for potential job candidates was both a difficult and enjoyable experience. I felt it helped me make better decisions about how to structure functionality around technical requirements and best practices according to the project at hand, not just meeting business requirements. Though my company’s app was a good guide for how and what I wanted to test against, it was a productive challenge trying to put myself in the shoes of the candidate, how they would think about coming up with a solution for each step, and finding a balance between skill testing and time constraints.
You can find the starting point on the master branch of the project, and my personal solution on, cleverly enough, the solution branch. If you found this project helpful in your own endeavors, feel free to fork and expand the feature set with a pull request, and don’t hesitate to ask any questions or offer any suggestions. Thanks for reading, and good luck!