Blog

Our First Swift Project

Apple announced Swift at last year’s WWDC as the successor to Objective-C to the surprise, dismay and excitement of many including ourselves. We knew that when the next iOS project starts at ustwo a new question to ask ourselves aside from device and iOS version would also be which programming language to use? (Swift or Objective-C).

To answer that we needed to get familiar with Swift as soon as possible to find out if it was production ready, and identify what advantages / disadvantages it would give us.

Learning the basics

“Swift is a new programming language for iOS and OS X app development. Nonetheless, many parts of Swift will be familiar from your experience of developing in C and Objective-C.”

As with any other programming language a good way to learn is by creating something so we decided to make ourselves a challenge like the one we might give to job applicants. We settled on a “Twitter App” - a small application where you would login to see your Twitter timeline.

As well as the sample project we used tutorials out there to explore the building blocks: variables, logic / control loops, functions and objects. The new Playgrounds feature of Xcode was an excellent way to do this and get practiced writing Swift early by experimenting with core types such as Arrays, Strings etc. Ruby offers something similar in its Interactive (IRB) console. Beyond that we tested things that were more iOS centric through such as integration with Apple’s Cocoa Touch frameworks e.g. can we present a list of data and run animations (UIKit) can we download some JSON and parse it (Foundation, Networking) and importantly can we use any existing libraries written in Objective-C should we have to.

Last but not least we experimented a bit with XCTest to make sure we could unit test our code properly. (albeit without support for mocking and stubbing that frameworks that Kiwi provide)

Though this was a good way to start quickly with Swift we have learned in the past few months that like with any other language this is a continuous process. The language still has some limitations and issues and is still evolving and changing so we just need to be prepared to adapt.

Onto Production

Since the answer to most of the above was yes we were happy and took Apple’s announcement to finalise the language version at 1.0 and accept apps written in Swift to the App Store as a green light to use it for the next project back in October (2014). Hence the next step was to choose or define some new coding style guide for the team to work with.

We decided to take what we knew from Objective-C and apply it to Swift in an attempt to take advantage of its flexibility and shorter syntax and make it as easy to read as possible. We still use verbose methods and variables names and spend time discussing type inference or the use of self with fellow iOS developers.

The Risk and The Reward

Technically we were ready to start our new project in Swift but there was one final piece of the puzzle missing: evaluating our choice from the project/client perspective. For us developers it’s so exciting to start a new language that sometimes we forget what that means to the client. We knew Apple had been working in Swift for a few years now and is investing a lot in it but the fear of the unknown is greater than the challenge of doing something different and new.

As we tend to work on projects with a long term view for maintenance and feature development, Swift felt like the right choice. Apple’s Cocoa Frameworks are still the same and we had already tested integration so we saw no risk there. The backup plan was if Swift wasn’t working out in the project for whatever reason we could start writing new modules in Objective-C and interoperate between the 2 languages in the same project (thankfully we didn’t have to go down that road).

We didn’t have any constraints here from the client and let them know our decision - one we felt it was in their interest i.e. to choose the new language given the potential lifespan of the project.

The Good, The Bad and The Ugly

The good was the speed at which we could write Swift after getting used to it compared to Objective-C. We’re quite fond of Objective-C for its readability and self documenting nature but there’s no denying that there’s less boilerplate required for Swift but yet what remains is a familiar style and object oriented constructs we know and love, combined with more modern language features. It felt like writing Ruby or a script based language with the power of being a statically compiled language and type safety built in.

The bad when writing Swift code in our iOS application at this stage (end of 2014) was actually Xcode which still had a lot of problems at the time. Not only it crashed often while writing code but the static analyzer reported the weirdest problems and the autocompletion of code was not working most of the times. Once you get used to this you start to see how an amazing language Swift is. You can write code faster than with Objective-C and to my surprise, everything looked so clean and easy to read. My fingers were definitely less tired at the end of the day.

I have to admit that at first I used to get annoyed by all the nil checks and optional bindings but it was not until after a while that I realized how this was making my code much more safer. We strive for stability in all our work but even still were amazed at how stable the app was especially with input edge cases. Another bad however was a crash in UIKit framework when customizing a UINavigationBar with a custom Swift UINavigationBar subclass (reference Apple Radar: 19373031)) forcing us to lower optimisation settings or consider rewriting the module in Objective-C until its fixed in future version of Swift or Xcode.

The ugly was later (towards the end of 2014) that as the project started to get larger with more modules and around 15,000 lines of code we started seeing an exponential increase in our compile times with each new file added. I think it’s fair to say that our increase of productivity writing in Swift started to become less and less significant when faced with such long Build > Run cycles.

Optimisations

We did the following to optimize our builds

  • Reducing the number of files (consolidating extensions)
  • Optional binding instead of force unwrapping
  • Build active architecture only on Debug builds
  • Disabling unit tests from running on Debug build
  • Removing any type inference in our code (particularly nested type inference)
  • DRY-ing up code earlier than usual
  • Using Objective-C for the few libraries we added when Swift one was available

Benchmarks

Here are some benchmarks of our build compiles times taken at the time (before and after our optimisations).

We used cloc to measure statistics using of our code base for comparison:

Before

~30 sec compile on a 6-core Mac Pro (default number of Xcode build threads)

perl cloc-1.62.pl . 722 text files.675 unique files. 102 files ignored.http://cloc.sourceforge.net v 1.62 T=2.97 s (194.3 files/s, 26251.3 lines/s)-------------------------------------------------------------------------------Language files blank comment code-------------------------------------------------------------------------------Swift 308 11400 4010 16822HTML 46 6360 17 9984Perl 2 713 1157 8044JSON 35 4 0 5380XML 42 1065 0 2848Objective C 42 913 1168 2473Ruby 39 381 423 1361CSS 2 115 19 503C/C++ Header 52 451 1744 431Bourne Shell 5 15 11 69YAML 4 6 8 60-------------------------------------------------------------------------------SUM: 577 21423 8557 47975-------------------------------------------------------------------------------

After

~24 sec compile on a 6-core Mac Pro (default number of Xcode build threads)

perl cloc-1.62.pl . 717 text files.670 unique files. 101 files ignored.http://cloc.sourceforge.net v 1.62 T=2.94 s (194.8 files/s, 26482.4 lines/s)-------------------------------------------------------------------------------Language files blank comment code-------------------------------------------------------------------------------Swift 304 11402 3982 16806HTML 46 6360 17 9984Perl 2 713 1157 8044JSON 35 4 0 5380XML 42 1065 0 2848Objective C 42 913 1168 2473Ruby 39 381 423 1361CSS 2 115 19 503C/C++ Header 52 451 1744 431Bourne Shell 5 15 11 69YAML 4 6 8 60-------------------------------------------------------------------------------SUM: 573 21425 8529 47959-------------------------------------------------------------------------------

We filed a radar about this a month ago and received a reply that its being worked on. 2 weeks ago Swift 1.2 became available as a developer preview in Xcode 6.3 Beta with support for incremental builds (reference Apple Radar: 18248514) and so far having tried it out is an amazing improvement to a developers compile times. It also comes with having to migrate to minor changes in the language. Dealing with syntax changes in the language is often hard work but because we always have access to betas from Apple, we still have some time to prepare.

Summary

When reading all the bad things about Xcode and Swift at this point you could ask if we ever had any regrets starting this project in Swift. The simplest answer is NO.

Swift was never a problem / blocker in our process. The time we had to prepare and learn the basics helped us throughout the project and Swift is just a wonderful language. It allows us to do everything we would do in Objective-C plus a lot more cool features like generics and templating, etc… It’s true that Xcode has provided us some bad moments and the Swift compiler is not that advanced yet but its relatively younger and looking at all the excitement we had writing code in a new language! It was worth it for us.

For the first time we were filing radars for everything we found and commenting in the Apple developer forums. We suddenly have this awesome feeling that we are contributing in some small way to the evolution of a new language. Each new release of Swift and official blog post is an excitement. We rush to check what has changed, what bugs were fixed, what improvements and new features were added to Xcode.

What you need to consider:

  • Motivation: desire to learn new language vs other things that need to be learned
  • Experience: comfortable learning a new language?
  • Time: deadlines for the project and put into practice
  • Compatibility: libraries, works well but check compatibility just to be sure
  • Adapting: potential language changes
  • Productivity: Stability. Toolchain is familiar but is still maturing (productivity)
  • Hardware: Xcode takes advantage of multiple CPU cores and hyper-threading during compilation. We were twice as fast by switching to machines with cutting edge i7 / Xeon architecture. This is something that should improve on more modest hardware support when incremental compiles are finalised (see above)

Like with anything new it’s a decision not to be taken too lightly but from our experience the investment has been rewarding. We don’t know what Apple’s future plans are, Objective-C is here but so too is Swift - we believe it is the future.

Further thoughts?

We put this out there to share our experience. Feel free to let us know your experiences too!