Hire the top 3% of freelance Swift developers.

Toptal is a marketplace for top Swift developers, engineers, programmers, coders, architects, and consultants. Top companies and start-ups choose Toptal Swift freelancers for their mission-critical software projects.

Hire a Top Swift Developer Now

We've been blown away by the level of talent we've been able to hire through Toptal.

Brad Rozran, Optimizely

Trusted by leading brands and startups

Our Exclusive Network of Swift Developers

Patrick DeSantis

Swift Developer

Patrick is a professional iOS developer who is passionate about quality code, UX design, and leadership. He had worked on both enterprise and consumer apps... with millions of downloads. He has been a solo developer, team member, and team leader. 

Hire Patrick

Stephanie Volftsun

Swift Developer

Stephanie is an entrepreneur and freelance software developer with 10 years of professional experience. She started 2 companies (Knotch, Bubby) which are bo...th still going strong. She's built products from the ground up and has built features on top of larger systems. In general, she love building products that delight people. 

Hire Stephanie

Stefan Progovac

Swift Developer

Stefan is a highly skilled iOS developer with a master's degree in physics. He loves both technological and artistic sides of software engineering. He has h...ad the pleasure to work on some popular enterprise-level apps used by millions of people for companies like Target, Best Buy, and Coca-Cola. He believes that app development is truly an art. 

Hire Stefan

Christopher Arriola

Swift Developer

Christopher is a mobile engineer with over seven years of experience creating native Android and iOS applications. He has a strong product sense and an eye... for design. His portfolio includes a social network with millions of users, to real-time messaging and more. He also is a strong advocate of RxJava and is currently writing a book called "Reactive Programming on Android with RxJava" (https://leanpub.com/reactiveandroid). 

Hire Christopher

Matthew Carroll

Swift Developer

Matthew is an iOS, watchOS, and tvOS developer, and a contributor to Apple's Swift project. He graduated from Georgia Tech with a BS in computer science in... 2002. Since then he has developed in C/Unix, Java/Spring, and iOS—most recently developing on iOS at The Weather Channel. He has been developing in Swift since the fall of 2014. He highly values clear communication and is available to travel to client sites. 

Hire Matthew

Colin Young

Swift Developer

Colin is a senior engineer and software architect with over 10 years of experience leading products and managing small entrepreneurial teams. He specializes... in high-value React/React Native consulting as well as serverless architectures. He is confident in several back-end languages and frameworks, including Node.js, Ruby, and Python, to deliver robust, performant API back ends and the clients and applications they serve. 

Hire Colin

Dan Napierski

Swift Developer

Dan is a software architect and technology professional focusing on applications of blockchain technologies. He has years of experience providing profession...al consulting services to clients ranging from startups to global corporations. He specializes in bringing rigorous testing and bulletproof code to tough engineering challenges. He has deep expertise in many aspects of artificial intelligence, blockchain, machine learning, and automation. 

Hire Dan

Josh Reynolds

Swift Developer

A Herculean nerd with hustle, Josh is committed to authentic engagement, intrinsic motivation, and epic betterment of projects, people, and plans. His passi...on for clean code, automated test, and continuous delivery has led to highly efficient success. Awesomesauce! 

Hire Josh

Ryan Bradley Lons

Swift Developer

Ryan is a senior level iOS and web developer with a strong passion for creating amazing user interfaces and experiences. He's very comfortable working anywh...ere in the development stack and has 10+ years doing it. He's well spoken and very easy to communicate with, is quick to respond, and excels at figuring out optimal solutions for any challenge you present to him. Ryan has an entrepreneurial drive and understands the challenges startups face. 

Hire Ryan

Petru Gabriel Lupu

Swift Developer

Petru is a developer who's spent the last 14 years in the mobile industry, publishing 100+ apps in the App Store. To any project, he brings in-depth knowled...ge of SDKs/libraries and iOS hardware/software, exceptional OOP skills, solid Node.js knowhow, and hands-on experience with RESTful web services in mobile apps. Besides his technical expertise, he’s also comfortable with Agile workflows, working with Git, and thrives in a team environment. 

Hire Petru

Hire Swift Developers Seamlessly with Toptal

Talk to One of Our Industry Experts
A Toptal director of engineering will work you to understand your goals, technical needs, and team dynamics.
Work With Hand-Selected Talent
Within days, we'll introduce you to the right Swift developer for your project. Average time to match is under 24 hours.
The Right Fit, Guaranteed
Work with your new Swift developer for a trial period (pay only if satisfied), ensuring they're the right fit before starting the engagement.

Tap Into World-Class Talent

  • Trusted Experts Only

    Trusted Experts Only

    All of our talent are seasoned experts who ramp up quickly, readily contribute as core team members, and work with you to minimize onboarding time.

  • The Right Fit

    The Right Fit

    We have a knack for matching you with the right fit. Start working with your new hire on a no-risk trial period, paying only if satisfied.

  • Scale as Needed

    Scale as Needed

    Hire in under 2 weeks and scale your team up or down as needed, no strings attached.

  • Seamless Hiring

    Seamless Hiring

    We handle all aspects of billing, payments, and NDA’s. Let us take care of the overhead while you focus on building great products.

  • Flexible Engagements

    Flexible Engagements

    Choose the engagement type that suits your needs — hourly, part-time, or full-time — with the ability to change anytime.

  • Expert Talent Matching

    Expert Talent Matching

    Focus on your project and enjoy support from your dedicated account executive and expert talent matcher.

Guide to Hiring a great Swift Developer

Swift is a general purpose, multi-paradigm, compiled programming language developed by Apple. It is powerful, intuitive, and applicable to broad range of platforms, including mobile devices, watches, desktops, and the cloud. Thanks to being open-sourced, it became popular very quickly. Swift's code is easy, interactive and fun. The syntax is concise yet expressive, applications are safe by design, and run very fast.

Read Hiring Guide
  • 53


How to Hire a Great Swift Developer

The Challenge

Swift has been diligently working on overtaking Objective-C since its introduction in 2014. As Objective-C’s successor to the iOS throne, it has all that a new generation programming language should have. It’s intuitive, interactive, safer, faster, more reliable, time saving, and free. Swift is designed to work with all Apple devices and to be fully compatible with Cocoa and Cocoa Touch frameworks.

Swift - One language to rule them all

Swift - One language to rule them all.

The original strategy was to make developers migrate to the new language on their own just by showcasing all its perks. However, the first version of Swift was rather unstable, buggy, and not fully compatible with Xcode.

The breaking point was in December 2015 when Apple’s strong preference for its newborn child was demonstrated by making it open source, and releasing the new big version with patches and updates. Swift 2 has been stable enough to be used safely in applications, which secured its place as the number one language of choice for iOS development.

Although Swift saw the light of day only two years ago, there is already a large community of developers who are considered to be experts on the topic. However, the difference between a developer and a great developer is their ability to adapt, learn, and keep pace with the rest of the world. Since Swift is facing a bright future, and there will certainly be many new updates coming each year, a great developer has to be on top of the evolutionary curve all the time. Finding such a talent to hire is not an easy task. So, this article offers a sampling of questions that are crucial to evaluating the breadth and depth of a candidate’s mastery of Swift.

Questions and Answers

Q: Describe Swift. What kind of a language is it? What are its main perks?

Swift is a compiling language whose source code is translated to machine code. It’s fully compatible with its predecessor Objective-C, and with Apple’s Cocoa framework. By open-sourcing the language, Apple made its vision clear that Swift is to be much more than only a language for mobile applications. New frameworks, like Perfect, are first attempts to make Swift a server side language too. The result will be that Swift developers and full-stack developers will have the power to create client and server side applications using the same language.

To mention some of the main advantages of Swift:

  • Optional Types, which make applications crash-resistant
  • Built-in error handling
  • Closures
  • Much faster compared to other languages
  • Type-safe language
  • Supports pattern matching

Q: Explain the main differences between classes and structures in Swift.

Classes and structures are the very basic building blocks for the majority of programming languages. However, there is a difference between them. To leverage them fully in Swift, we need to be aware of all the possibilities they offer. There are certain principles every developer should know and adhere to.

Let’s start with attributes that classes and structures have in common:

  • Both conform to protocols to standardize functionality to a particular purpose, the interface.
  • Both can extend their functionality to add additional methods without modifying the original class or structure.

However, more important than knowing what they have in common is to know how they differ:

  • Classes are reference types - they are not copied when they are assigned to a different property, nor when they are being passed to a function.
  • Structures are much faster. Class instances are allocated on the heap, while structure instances are on the stack.
  • Structures do not support inheritance.
  • Structures provide default initializers for all properties which don’t have a default value:
struct Person {
    let name: String

let patrik = Person(name: "Patrik")

let patrik2 = Person() // does not compile, name property needs a value

Q: Explain generics in Swift.

Complex applications require clean code without any duplication. Here, generics come in handy as they can help us to avoid unnecessary duplication. In general, generics are considered as one of the most sophisticated features of Swift, and they should be used as much as possible. They enable us to write classes and methods without specifying the types they use. Swift uses generics internally wherever it is possible.

Let’s have a look on one of the best example, arrays, as they can store any types. In our example, we will implement a simple data structure, Queue, to demonstrate how powerful and useful generics can be:

class Queue<T> {
    private var data = [T]()
    func enqueue(item: T) {
    func dequeue() -> T? {
        return data.count == 0 ? nil : data.removeFirst()

let q = Queue<Int>()

Here, we removed the need to create Queue for other types that we would use in the application later. Our Queue can contain any type, and we were able to define it in one place. It saved us a lot of time that would be otherwise spent on setting the Queue each time later.

Q: Explain the lazy keyword.

An initial value of the lazy stored properties is calculated only when the property is called for the first time. There are situations when the lazy properties come very handy to developers. Imagine that the property needs a significant time for initialization, like when instantiating an array of controllers for storyboards used for UIPageViewControllers.

class MyController: UIPageViewController {
    lazy var myControllers: [UIViewController] = {
        guard let storyboard = self.storyboard else { return [] }
        let controller1 = storyboard.instantiateViewControllerWithIdentifier("Controller1")
        let controller2 = storyboard.instantiateViewControllerWithIdentifier("Controller2")
        let controller3 = storyboard.instantiateViewControllerWithIdentifier("Controller3")
        return [controller1, controller1, controller1]
    override func viewDidLoad() {
        let _ = myControllers
        let _ = myControllers

In our example, we called myControllers two times in viewDidLoad (it is just for testing purposes, to see how the initialization works). Our lazy variable contains a print statement to demonstrate what’s happening under the hood. After calling two times let _ = myControllers, there is only one message in a console log. That’s because the second time lazy variable is already initialized, and there is no need to do it once again.

Q: Discuss how to pass a variable as a reference.

Before getting into the discussion, we need to mention that there are two types of variables: reference and value types. The difference between these two types is that by passing value type, the variable will create a copy of its data, and the reference type variable will just point to the original data in the memory.

In Swift, all class instances are reference types. A variable with a class object is just a pointer to the memory. The same applies for functions as parameters. Consider the example:

class A: CustomStringConvertible {
    var name = "Patrik"
    var description: String {
        return name

func changeName(object: A) {
    object.name = "Thomas"

let myObject = A()
print(myObject) // Thomas

Here, an instance myObject is passed to the changeName function, and there is no need to mark parameters as reference types. Instead, we simply need to know some rules about how they behave when used with different parameter types. In this case, the print(myObject) will write “Thomas”.

Structures, Arrays, Strings, and Dictionaries are value types. To achieve a similar effect, to pass a variable to a function as a reference type, we need to add inout keyword before the parameter’s declaration and ampersand before the variable. Let’s consider a similar example:

func changeFirstElement(inout input: [Int]) {
    input[0] = 9

var array = [1, 2, 3]
print(array) // [9, 2, 3]

Q: Explain what defer is, and when you should to use it.

Swift 2 introduced the new defer keyword which provides a block of code that will be executed when the outer block is going to be finished. We could say that defer block will be executed in the case when execution is leaving the current scope. Consider the following code, and try to answer what the output will be.

func write() {
    defer {  print("end") }
    print("start for loop")
    for i in 0...5 {

As we previously stated, the defer block will be executed at the end of the function even if it is declared in the first line of the write() function.

The output result will be:

start loop

Now, a little more complicated example:

func write() {
    defer {  print("end") }
    print("start loop")
    for i in 0...2 {
        defer { print("defer ", i) }

The output is:

start loop
defer  0
defer  1
defer  2

It’s worth noting that the defer statement in the “for loop scope” is executed after each iteration of the loop. That’s because defer’s parent scope is a loop scope.

Nesting defer block in if statements will do the same like in a for loop.

func write3(input: Int) {
    if input > 0 {
        print("the number is greater than zero")
        defer { print("defer positive") }
    print("input is ", input)

The output is:

the number is greater than zero
defer positive
input is  10
the number is greater than zero
defer positive
input is  10

Using defers can significantly help programmers to avoid duplication, but it is crucial to know defer’s behavior and when it’s executed. Simple print functions can verify whether the developer understands the issue.

Q: Why it is better to use higher order functions? Explain with examples.

Functions that take another function as a parameter, or return a function, as a result, are known as higher-order functions. Swift defines these functions as CollectionType. The very basic higher order function is a filter. It’s a function on the array which accepts another function that will be used to return a new filtered version of the array. The main purpose of the higher functions is to help us write code with fewer bugs and in less time. At first glance, these functions might be scary, but a good developer should use them as much as possible.

The fact that we can take one function and put it into another function allows us to compose a lot of small functions into bigger functions. If we are aware of that, the readability of the code will be much higher.

Let’s assume that we have an array of numbers. How can we select only those that are bigger than zero? A very simple approach is:

let numbers = [-10, 4, -3, 5]
var positive = [Int]()
for n in numbers {
    if n > 0 {
print(positive) // [4, 5]

However, wouldn’t it be better to write less code and in a more elegant way?

let numbers = [-10, 4, -3, 5]
let positive = numbers.filter { (value: Int) -> Bool in
    return value > 0
print(positive) // [4, 5]

In the code example above, filter function will loop over each value, and for each value, it will pass it to a callback function as the current value. A callback function will then return a Boolean value to determine whether this value should be in the output array or not.

Swift enables us to use a shorter version of closures by inferring the types of its parameters and the type of the value it returns. As a result, there is no need to write a full declaration when the function is directly passed as a parameter.

let numbers = [-10, 4, -3, 5]
let positive = numbers.filter { $0 > 0 }
print(positive) // [4, 5]

Swift also provides the map function which returns a new array containing of all the new mapped values and only with one line of code.

let numbers = [-10, 4, -3, 5]
let strings = numbers.map { String($0) }
print(strings) // ["-10", "4", "-3", "5"]

To sum all values in an array, there is a reduce higher order function to help us achieve it.

let numbers = [-10, 4, -3, 5]
let sum = numbers.reduce(0) { $0 + $1 }
print(sum) // -4

Q: What are the best practices to group application settings to make the project as clean as possible?

Every project includes some custom settings, like API keys, names of NSUserDefault keys, or a palette of used colors in the application. Small projects do not require any precise rules for this to work properly. We can simply use something like the following:

label.textColor = UIColor(red: 34/255, green: 36.0/255, blue: 38/255, alpha: 1)
NSUserDefaults.standardUserDefaults().setBool(true, forKey: "isTutorialShown")

However, projects tend to grow, the design of the application will change, and we need a better system to group ‘’shared” data in one place. We need a way to change just one line of the code, like the application color, and have it propagate properly to the whole project.

There are multiple approaches to solving this problem. Let’s examine one possible solution:

struct Color {
    static let appColor = UIColor(red: 34/255, green: 36/255, blue: 38/255, alpha: 1)
    static let greyColor = UIColor(red: 131.8/255, green: 131.8/255, blue: 131.8/255, alpha: 1.0)

struct Settings {
    struct NSUserDefaults {
        static let isTutorialShown = "isTutorialShown"
    struct APIKey {
        static let fabric = "xxx"

By wrapping similar properties together, we can significantly reduce bugs, like using the same key in NSUserDefaults for two various properties. Additionally, this way provides us a spell check if we wrote the key correctly. Also, if we decide to remove some key or color, removing one line will inform us which files used that deprecated key. There are so many benefits for using all the keys in one place.

However, we know that creating Color or Settings struct in a global scope level is not the best approach, as it is like a global variable, which is a bad practice. We should put these settings into a wrapper, which is then directly connected with a type of item.

extension UIColor {
    struct MyProject {
        static let appColor = UIColor(red: 34/255, green: 36/255, blue: 38/255, alpha: 1)
        static let greyColor = UIColor(red: 130/255, green: 130/255, blue: 130/255, alpha: 1)

extension NSUserDefaults {
    struct MyProject {
        static let isTutorialShown = "isTutorialShown"

The result of using the keys will be:

NSUserDefaults.standardUserDefaults().setBool(true, forKey: NSUserDefaults.MyProject.isTutorialShown)
label.textColor = UIColor.MyProject.appColor

Leveraging Swift extensions can give us a sophisticated way how to group all the necessary settings and make the design cleaner. Creating one separate file for all extensions is also a good idea, and then we will get design changes much faster than by going through each of the files and changing colors manually.

Wrap Up

Answering questions we covered in this article should be a piece of cake for any top level Swift developer. The truth is, the language itself is not difficult to learn and use. However, keep in mind that whether your developer is good or not will be revealed during the time when more and more new updates are released and new features incorporated. Swift’s mastery is about being able to understand correctly and apply new principles in the shortest period possible to keep your application’s functionality in the lead.

We hope you find the questions presented in this post to be a solid foundation in your quest for the top Swift developers. Finding such candidates is well worth the effort, as they will undoubtedly have a significant positive impact on your team’s productivity and results.

Top Swift Developers are in high demand.

Get Started