Objective-C U L8R: A Swift Transition
At Prolific nothing is ever set in stone. Whether an idea, a technique, a process, or a best practice – things evolve, and so do we. As a company we strive to stay on top of trends and technology, and we’ve created an environment where taking risks to reach that goal is an integral part of our culture.
When Swift was announced in June 2014, the entire Apple developer community was extremely excited about it. After all, Objective-C had been around for 30 years and was the only effective option we had when it came to developing applications for Apple devices. Even on the Android and server side, Swift had people intrigued.
From the very first day it was introduced, we looked at the Swift evolution with attention and tried to figure a way to jump in as a team of engineers who only knew Objective-C. When would be the right moment? How viable would Swift be long term? How would we do it? Then WWDC 2015 seemed to answer most our hesitations. Swift 2.0 was introduced and made open source! No more excuses, no more waiting, it was time to embrace the new language.
And, in 4 months we were to start our first Swift project from scratch.
Back in June 2015, everyone was excited about Swift but barely anyone had experience writing production quality code with it. For us, it was that introduction of Swift 2.0 that was the turning point. We had seen the language mature over the course of a year and it was time to dive in.
Yet, there was real risk in transitioning our team of 20+ engineers to use Swift.
We had operational issues to combat. Majority of us had never written code in Swift, much less a production quality app. Moreover, our existing processes around continuous integration, tools, and code audits were built around Objective-C.
There were technical issues to combat. Our existing code bases and collective experience was with Objective-C. We relied on a number of public and private libraries in Objective-C. And, we were not familiar with integrating Swift into Objective-C projects.
There were also business issues to combat. We were working on eight concurrent projects, many of which represented long-term business relationships. Would we transition apps we had been working on for months, or would continue to be working on for years? How did we accurately explain to our partners the implications of using Swift, while also getting them onboard?
Despite the challenge, we wanted to move forward. Our excitement was a key factor, but more important was the proverbial writing on the wall. Suddenly, Apple only used Swift – for its documentation, for sample code, and for WWDC keynotes. Even open sourcing Swift indicated the care Apple was putting into making Swift something the development community would invest in. As Prolific prides itself on being on the cutting edge of technology and of our craft, switching to Swift was inevitable.
Swift had moved into a place where a lot of the v1.x shortcomings were fixed. The v1.2 to v2.0 transition felt like a whole new world – the update brought a lot of breaking changes which made transitioning hard for some but we felt like the language had attained the right level of maturity. It no longer felt like writing Objective-C in Swift. We had followed the evolution and understood what it meant to make our move at that moment. We were making an educated decision.
As our company operates closest to an agency model, we start on new projects every few months, often lasting 4-6 months in duration. This setup lends itself to continually being able to learn new things about building an app from scratch, which afforded us the ability to charge into Swift. Legacy code and longer term projects were also part of the equation, and we knew we would need to make a decision regarding those. Thanks to our process, existing code bases were flexible and so were our teams. It comforted us that including those projects in the transition wouldn’t be a limiting factor.
While that flexibility may have been our biggest advantage, it is also what made it hardest. Getting disparate projects and engineers in line would require a plan.
The transition was about getting us all to a place where we could think Swiftly. It started with education, incorporated process changes, practice, and ultimately disseminating the knowledge we gained. The plan was outlined as followed:
- Provide the team with Swift books and encourage review of the Apple Swift Guide
- Start requiring that blog posts, presentations, and sample code be only in Swift (a la Apple)
- Incorporate Swift into existing Objective-C projects, especially when starting new features
- Have every engineer re-take the code challenge used for new hires – but in Swift
- Engage engineers in reviewing each other’s code challenges
- Discuss what we thought was good/bad/had potential about what we implemented
- Update internal processes that rely on Objective-C to be ready for Swift
- Work on a Style Guide over a few months span, as we learned about best practices through implementation of the code tests and our first all-Swift project
- Work on Swift libraries for ourselves and the community
This plan was put into motion last June – and we’ve come out a year later all the better for it. That being said, it presented its own challenges. The learning curve was too steep to have the entire team keep the same pace. It was especially hard for engineers to find time to work on re-doing their code tests while working full-time on products.
We ultimately re-lived a lesson we all know well – the best way to learn is through doing. We were only able to spare two days per engineer for them to put their heads down on their code tests, and that wasn’t enough. However, it was important to have a concrete goal for everyone to work towards, especially for the engineers who were to stay on Objective-C projects for the time being. We also found that we had to lean on the people who were particularly interested and motivated to learn and share. Not everyone has the bandwidth to do this – but those who do should be encouraged.
It took about a year. A year of being insistent on incorporating Swift into whatever we could – presentations, readings, new projects, new features on old projects, and so forth. And, it was an amazing year. The time we “lost” in these learnings manifested itself into a gain in terms of code writing efficiency. Code became easier to read and write, less verbose, and included new paradigms we weren’t leveraging before. We’re now comfortable bringing engineers of any level onto a new project; we have enough Swift savvy among our engineering leads to handle any situation.
While this was an overall success, not everything went perfectly. As far as hurdles, I have to mention our dependency on Objective-C. We had to make tough decisions around giving up on dependencies we had been using for years – should we keep them? Find their Swift counterpart? Rewrite them? The bright side of working through these questions was it helped us greatly refine our open source initiatives.
Another difficulty we encountered was the learning curve. By end of the process, naturally, everyone wasn’t on the same page. Mentorship played a great role – by learning from each other and pairing engineers who had already worked on a Swift project with those who hadn’t, we helped fill in the gaps.
Last but not least, I have to mention good old Xcode. Some consider it a friend, most see it as a liability. We had issues with it before Swift, and the new language didn’t make things better. It is still impossible to quickly refactor Swift code, the compiler takes longer and crashes more, sometimes code formatting and syntax highlighting go poof and you’re basically looking at Vim, but without the powerful key bindings.
Hopefully someone will tell Xcode 8 about Swift…Here are a few figures that reflect our current landscape:
- 5 projects in 100% Swift
- 7 hybrid projects in Objective-C and Swift
- As of May 2016, a third of the code base in active iOS projects at Prolific is Swift:
- 7 open source projects, and counting:
- Swift Style Guide – a Style Guide for Swift.
- Caishen – a Payment Card UI & Validator for iOS.
- Simcoe – a simple, light analytics framework for iOS.
- Yoshi – an in-app debug panel for iOS.
- Marker – a light wrapper around NSAttributedString.
- Optik – a library for displaying images from any source, local or remote.
- Cake – a Cocoapods wrapper allowing for greater control over your workspaces
- Shout out to Gloss – a JSON parsing library written by a Prolific P!
- 1 internal tool in Swift that helps automate our code audits, plus a specialized fork of SwiftLint.
- A vast reduction in verbosity. On average the number of lines of code per file went down 56%:
- A greater level of comfort with Swift. We took a survey amongst our engineers and the majority of them feel fluent in Swift:
So, what’s next?
More Swift! Swift 3.0 is around the corner and we’re just as excited – except we feel more prepared; and, that feels great. Objective-C has been a good companion for so many years, but we have no regrets about adopting its modern alternative and are glad we invested in what looks to rule the future of Apple app development. We’re also looking toward more open source, which we hope you’ll find helpful.
It was a year ago we started the process of transitioning our team to use Swift. Today we are proud to say that we succeeded in starting a difficult process and really getting somewhere with it. We are far from done, as there is always room for improvement and there is always something to learn. But, it’s a joy to be able to say we’re confident in our ability to deliver 5-star apps – written in pure Swift.