We talk testing, mentoring, and the future of Swift
Antoine van der Lee is perhaps best known for being one of the tallest iOS devs you’ll ever meet. After that, though, he’s also known for the talks he delivers, his excellent Swift blog, and his work at Dutch digital giant WeTransfer.
As he’s been active on the Swift scene for some years, and a programmer for much longer, I got in touch with Antoine to ask for his views on testing, mentoring, and the future of Swift…
Hacking with Swift: I want to start by asking you about WeTransfer, where you work on the Collect app. This is clearly a huge piece of software – what kind of testing and CI systems do you have in place to make sure you ship a stable app every time?
UITableView, no CI and no QA in place. This improved over time as I’m a person who constantly seeks for improvements – and luckily enough the whole Collect team is too. That’s also the reason why we started this year with revisiting our QA, CI and release processes.
“Apart from that, we strongly believe in unit tests. Our main app contains 500+ unit tests while our core framework is tested with 1100+ unit tests.”
We now have a so-called release train, which leaves every Monday with the latest green-light build available. We currently use a daily cron job on Travis CI to deliver a daily build using Fastlane. This will also create a draft release on GitHub including our “next version” section from our changelog.md. Our QA team tests the build and turns the draft release into a non-draft release to mark it as a “green-light build”. Our weekly cron job on Monday will pick the latest non-draft release and submits it to Apple for review. It also creates a pull request to update develop with a new changelog.md which will have a clean “Next” section.
Our QA team is located in Amsterdam, as well as in India. The time zone difference with India brings us a benefit as we receive daily test results the moment we arrive in the morning. They perform daily smoke tests combined with targeted testing based on the changelog.
Apart from that, we strongly believe in unit tests. Our main app contains 500+ unit tests while our core framework is tested with 1100+ unit tests. This results in almost 90% code coverage, which for us is high enough – it’s hard to get to 100% either way.
Performance here is key as we focus on optimizing our CI runs as much as possible. Therefore, we’re not using UI tests as they’re still pretty slow. This sometimes means that we need to do a hotfix for a broken UI, but this is something we accept doing. We’re also running all our unit tests offline, using our open-sourced framework Mocker. This speeds up both our tests and development, as we can easily create mocked responses and test a certain scenario. Snapshot testing is something we’re currently looking at, as it’s a fast and useful way to validate our UI.
HWS: As someone at a big company who has been coding for almost a decade, you must have a lot of experience in mentoring others and passing on hard-won knowledge – what advice do you have for other senior developers?
AvdL: Try to stay humble and not judge someone on their junior, intermediate, or senior role – you’ll be surprised how much they know and how much you can learn from them. Be open for feedback and be aware of your knowledge. It can be hard to give feedback, but with honesty and good explanation you can really help anyone grow. My best advice here would be to give feedback at the moment you encounter something which can be improved. This saves you from explaining the situation and makes it really clear what can be improved.
“It can be hard to give feedback, but with honesty and good explanation you can really help anyone grow.”
In code reviews, the focus is on delivering the best quality code and giving constructive feedback to each other. I think it goes hand in hand with the mindset that when we find a bug its team effort and we will look for a good solution.
We try to say “we” instead of “you” when giving feedback, for example “we could do this better like this” sounds a lot nicer than “you can do better by” – that feels a lot more personal and sometimes even attacking. It’s subtle but really makes a difference for us. At WeTransfer we don’t do specific in-house training or 1-to-1 meetings regarding development. We try to continuously improve, sharing knowledge and feedback.
As we’re addicted to automation we try to improve common tasks with tools like Danger, Fastlane, and SwiftLint. As a result, common feedback on pull requests is covered by our WeTransferBot. Our CI system is open sourced to easily integrate it in any of our GitHub repositories and contains our SwiftLint, Danger and Fastlane setup.
HWS: I know you’ve spoken about and written about architecture a lot, but this continues to be a problem many folks in our community face. How do you manage complex architectural decisions in your own code?
“To align our team we’ve created our own coding guidelines based on the now archived GitHub style guide.”
AvdL: Architecture is hard, indeed. Even if you think you’ve got it right, a few months later and your project could really use a big clean up. We are still a relatively small team with only three developers, but when the team grows it's even harder to keep control over the architecture of your code. To align our team we’ve created our own coding guidelines based on the now archived GitHub style guide. We use SwiftLint together with Danger as mentioned before to keep our code quality up.
Throughout the project we try to align as much as possible with iOS patterns, combined with MVVM. This means that we use delegates, datasources, and extensions, but also Core Data instead of a framework like Realm. This helps us easily migrate to newer Swift versions, as well as making sure the project is easy to adopt by any new colleagues. Over time it has proven to work where new developers were up and running in less than two weeks.
It does happen that we run into new cool frameworks or architectures on for example conferences or meetups. We discuss them internally and we try to evaluate whether it’s worth the effort to start migrating all our code to a new architecture with as a result an inconsistent project structure for at least a certain time. Most of the time our project is simple enough to stick with our MVVM and iOS patterns.
HWS: Previously I watched a video of you talking about functional reactive programming, but that’s a complicated status in the iOS community – it’s never really caught hold. Why do you think that is?
AvdL: It’s funny that you ask! At the time I did that presentation I was a real advocate for using Functional Reactive Programming (FRP) in production apps – it’s a perfect example of a framework you try out and you can’t stop using. I remember my first days at WeTransfer where I joined a team of 3 experienced iOS developers. As you might expect, the first thing I missed was my lovely FRP framework. I even found it hard to think of code solutions without FRP!
“It turned out that there was always an easy way to solve the same problem with the code that aligned with the Apple APIs, not using FRP.”
My new colleagues were strict though. My job before WeTransfer was at an agency where I could merge code without reviews and I was one of a few seniors there. I basically could do what I want, but that changed at WeTransfer. I had to convince my three new colleagues to add a big dependency like ReactiveSwift or RxSwift. It turned out that there was always an easy way to solve the same problem with the code that aligned with the Apple APIs, not using FRP. I now sometimes still laugh with old colleagues and my current colleague Sam, as my perspective changed completely.
Functional Reactive Programming can make your code look really nice. Error handling and asynchronous code suddenly look a lot easier to manage. The downside is that you add quite a big dependency and a new way of programming which your colleagues need to adopt. This makes it harder for new developers on the project to get up and running. Besides that, a downside you often hear is that debugging is hard with a long stack trace which is hard to follow.
Those are reasons why I think it never really caught hold, combined with the fact that the default iOS SDK often contains enough to solve common problems. I also wonder what a new feature like async/await will do with the adoption of FRP framework, as it might solve common use cases in a nice and Swifty way.
HWS: More recently I saw you speak in Italy about speeding up as an iOS developer, which is always going to be a hot topic. I know many people feel like they aren’t working as fast as other people, so what are your top three tips for help folks do more with less time?
AvdL: My best tip here is obviously to watch that recording or read my summary blog post for that presentation!
“Xcode is your best friend, so make sure you know handy shortcuts”
It all starts with recognizing repetitive tasks. For example, as soon as you see that you copy the same code every time again, start thinking about a shared code solution like an extension, code snippets or a file template. Xcode is your best friend, so make sure you know handy shortcuts like Ctrl+Opt+Cmd+G to re-run your latest test or Ctrl+Cmd+R to run without building and turn yourself into an Xcode expert.
The last tip and one of the most impactful things that helped me to be more productive is to create focus. I close my email at 10 am, turn on “Do not disturb” and I only check pull requests in the morning. Together with my two meeting days a week I find myself often in my flow to deliver that new feature, right on time!
HWS: You’re working really hard on your blog right now, which is great to see – there’s a lot of new Swift tips and techniques. What kind of response are you getting from the community?
AvdL: Yes, it’s my new addiction! It’s been such a great experience so far and the responses are all positive. People I don’t know are reaching out in person or on Twitter, telling you they like the work you do. It’s a big motivation to continue writing. A fun fact as well is that I slowly see more and more searches on Google for SwiftLee, making me think I’m building a name now!
“I get asked a lot about how to start your own blog. The best start would be to not spent too much time on your first blog set up.”
I decided to start writing weekly in May 2018. The main purpose was for me to dig into Swift topics, learn from it, write it down and share it on my blog. A sort of win, win situation which forces me to dig into something new every week. Besides that, I hoped that it would enable me to speak more at events. On one hand, because I would gain more visibility to the community, but also because I could use the knowledge from blog posts in my presentations. My “Speeding up as an iOS developer” talk is a perfect example of content from my blog, which made it quite easy to create the content of the talk.
I get asked a lot about how to start your own blog. The best start would be to not spent too much time on your first blog set up. Start with a product like Wordpress, which enables you to move fast and focus on content. Creating consistency is key to gain followers and to make yourself structured in blogging frequently. Also, don’t create blog posts which take days to finish. This will make it harder for you to finish the post and you’ll probably rewrite a lot after reading it again. Telling yourself to write a post in an evening creates pressure and focus to finish.
I’ve told myself from the beginning: “My target user does not like reading and I don’t like writing, so keep it short and focused”. Don’t get me wrong, I do like writing (now at least) and probably a lot of my users like reading as well. However, this sentence of thought helps me to stick with my value of writing relatively short and to the point blog posts. So far I’ve always written my blog posts on a Monday evening within a few hours.
HWS: Finally, let’s talk about Swift. It’s really starting to settle down now, but how do you think it will continue to evolve in the future?
AvdL: Oh man, I remember those days with Swift 1.2. I had the luck of starting a project fully in Swift at that time, but what a pain it was. Incremental building didn’t exist! Nowadays, Swift has grown up and it’s a lot better. Combined with the great community around we can feel quite lucky I would say!
“I’m looking forward to benefiting from ABI stability and see what it does to our app startup time, as well as to see how it impacts future Swift development.”
It’s also great to see how Apple changed over time. The language is open sourced, more and more Apple developers are speaking at conferences and the swift.org blog is frequently updated. It’s a great feeling to receive a new Swift version and try out the new features. I’m looking forward to benefiting from ABI stability and see what it does to our app startup time, as well as to see how it impacts future Swift development.
One thing I really can’t wait for is async/await. I really want to play around with that to see how it can improve our codebase. To keep an eye sharp on new updates I’m following the Swift blog combined with the Swift Weekly Brief. I feel bad that I didn’t contribute to the Swift Evolution, but chose to focus on other things until now. Maybe it’s time to rethink this and start my own contribution? Oh well, let’s see!
SPONSORED Building and maintaining in-app subscription infrastructure is hard. Luckily there's a better way. With RevenueCat, you can implement subscriptions for your app in hours, not months, so you can get back to building your app.
Paul Hudson is the creator of Hacking with Swift, the most comprehensive series of Swift books in the world. He's also the editor of Swift Developer News, the maintainer of the Swift Knowledge Base, and a speaker at Swift events around the world. If you're curious you can learn more here.
Link copied to your pasteboard.