iOS is an enormous platform encompassing over 2711 classes, 644 protocols, and 125 frameworks. When preparing for an iOS interview, the impulse to review absolutely all API documentation may be self-defeating; as it is impossible to know and intelligently recall every nook and cranny. So what should we focus on? What are the high points every competent iOS developer should know for an interview? The following list serves as a ‘gut check’; consider these areas to be the baseline skills required to land a job writing mobile code for someone else. It is assumed that you have also researched and are familiar with other miscellaneous, niche technologies employed by the candidate company.
Study the HIG
The notorious H.I.G. That’s Apple talk for ‘Human Interface Guidelines.’ While not a strictly technical document, the HIG describes in great detail the design decisions, affordances, and proper usage of each Apple provided UIControl and navigation paradigm. It is the manifesto of why Apple apps ‘feel’ the way they do. Make sure to review it in it’s entirety and take note of the acceptable use cases for each control.
Review Appstore Guidelines
An app has little business value if it cannot pass an App Store review. Know exactly what types of apps are allowed, and which are not. Study and take note of the grey-areas and situations that result in rejection. Rules involving Apple Pay, background execution, and in-app purchases are required knowledge. Take note of a time where you had an app rejected, and what changes were made to pass review.
Know thy programming language. All of it.
Swift is the future of iOS development. This fact is undebatable. However, this fact does not mean the millions of apps within the Appstore, or all of Cocoa Foundation will suddenly turn to Swift overnight. Apple may be magic, but this is computer science. It is very likely the candidate company has legacy Objective-C code which must interface with Swift. In the case of a greenfield project, fluency in Objective-C is still a necessity. UIButton action actions, NSOperation and other core parts of iOS still require dispatch through the Objective-C runtime.
Objective-C Fluency
Be able to explain ‘message passing’ and how this relates to Objective-C. (and how this is different in Swift) Get in deep. Read through The Obj-C Runtime Reference and objc.h header file. Understand what ‘key-value-coding’ really means, and what it means for interfacing with Swift.
Porting legacy Objective-C code over to Swift is a good way to test your skill. Make sure you understand how Obj-C nullability annotations work and how they contribute a type-safe, cross language interface.
Know the core aspects of Objective-C:
- Protocols and how these are different from Swift Protocols
- Categories
- Class extensions
- Message passing.
- Toll-free bridging between Foundation types.
Swift Fluency
Fortunately, Swift playgrounds provide an excellent place to get comfortable with the more esoteric aspects of the language. Switch pattern matching, where
clauses, and unwrapping enum associated data are powerful techniques which can save time during a coding test.
Know why, and when to use the core aspects of Swift:
- Generics. Create your own re-usable Stack or Queue data structure.
- Value Types, Enums and Structs. Know how these are different from a class and when to use a value type instead of a reference type.
- What ‘protocol oriented programming’ really means.
- Swift Extensions
- Take a tour through the Swift standard library protocols. Create your own custom collections employing the SequeueType protocols.
- Swift error handling.
defer
,try!
,try?
,catch
,throws
Auto Layout and Size Classes
The iOS world changes almost each year with a new supported interface-size. Adaptive interfaces are here to stay, and fluency in Auto Layout is a required skill to ensure your UI is operable everywhere.
Other than competency with Auto Layout within Interface Builder, know how the Auto Layout system interfaces with UIView
subclasses. Know where and when to use the methods layoutIfNeeded
, layoutSubviews
, setNeedsLayout
. Be comfortable with programmatic Auto Layout via the NSLayoutConstraint
class.
Presently, Size Classes can only be configured through storyboards. Competent ‘adaptive UI engineers’ must be comfortable with designing a layout from scratch and adding/removing constraints based on the various device size class. Memorization of the common device sizes and their associated size-classes can definitely make you look savvy.
Networking
No app is an island. There is a very good chance, the next app you are paid to work on will interface with a backend service. The baseline for this is typically a working knowledge of the HTTP protocol. Be able to test a REST service using the cURL command-line tool. On iOS, the NSURLSession
group of classes provide a fantastic, high-level network programming interface. Know how to accomplish (at least) these tasks:
- Send a user-defined header value on every request.
- Configure the URL cache and ensure the same cache is used for all requests.
- How to write asynchronous, thread-safe network code.
- NSURLComponents, and their usage with an HTTP ‘GET’ request
httpBody
encoding, and how-to upload a picture and other arbitrary data to a network endpoint.- Type-safe handling of response data. This is usually JSON data, but don’t assume. Be able to decode raw NSData blobs into arbitrary data formats. Demonstrate knowledge of error-handling and defensive-coding techniques.
Data Persistence
Every app needs to store data; whether that be in the cloud, a temporary cache, or temp files. Mobile platforms are a resource constrained environment and thus require more care in choosing a persistence strategy. The chosen persistence has a direct impact on the entire UX of the application. Chose poorly, and the user can suffer data loss, and a degraded UI as the data layer fights for main-thread cycles. Be able to talk about alternate persistence strategies, and how-to combine different storage options to meet exotic edge cases. Know the hard technical details. Persistence is too important to fluff your way through by only knowing theoretical generalities.
Study these persistence technologies:
-
Core Data, the most common data persistence strategy on iOS. Make sure to know at least two different Core Data architectures and the benefits of each. Know exactly what
mainQueue
andprivate
concurrency type means. -
NSCoding is still a relevant data persistence strategy and may be found in older codebases which did not require the object-graph querying capabilities of Core Data. Know when to use NSCoding and how this relates to Swift datatype.
-
NSUserDefaults is the top-dresser drawer of persistence solutions. So easy to use, it’s over-use can accumulate technical debt when a more full-featured, relational solution is a better fit. Know what kind of data is appropriate to stick in NSUserDefaults, and when to use something else.
-
3rd party frameworks (Realm, FMDB, etc). Core Data isn’t the only game in town. To round out your knowledge, check out some of the third party mobile persistence frameworks. Compare them (in a meaningful, technical manner) to Core Data.
Memory Management
Manual
With ARC enabled, the compiler automatically inserts retain
, release
, autorelease
calls for us. However in legacy codebases (or those that are very opinionated) manual memory management may still be in use. Make sure you know how-to write code without the help of ARC. Within Swift, know how to work with unannotated, CoreFoundation APIs that return UnManaged<T>
type.
Automatic Reference Counting
Cocoa does not rely on garbage collection. So how does your program know when to free memory? Fundamental knowledge of reference counting is a required skill for even the most novice iOS engineer. Ensure you know what a ‘retain cycle’ is, and how they are created.
Understand the ObjC and Swift storage semantics of __block
, weak
, strong
, unowned self
, and weak self
.
Memory and the concept of ‘ownership’ must be taken into account when designing an object oriented system within Cocoa.
Instruments and lldb
Bugs happen. Speed in determining what went wrong is an essential skill for any professional programmer. You may be asked during the interview to debug a common problem within a sample app. Be sure you are familiar with the common Instrument templates for diagnosing these problems:
- Memory leaks and reference cycles.
- Slow UI performance
- Slow Network performance
- Slow animations
- Bad Core Data performance
The Apple tech-note iOS Debugging Magic contains many other worthwhile compiler flags and other debugging techniques.
Know what you’re doing
A vague understanding of hard technical concepts will not get you far in an interview. It is the interviewers job to separate the ones who ‘can do’ from the hand-waving, buzzword dropping fakers. If you don’t know something for sure don’t be afraid to say so. During a code test or white-board interview, know the purpose behind every line of code and how it contributes to solving the problem.
Keep Trying
Just like juggling, cooking, or hang gliding, interviewing takes practice. Maintain a good attitude about the end result, no matter what happens. Bombing an interview may be a blow to the ego, but taken as a learning experience, can sharpen your interview skills for the next one. After an interview, record all the questions you feel could have been answered better, or topics you may need to investigate. Good luck!