Wrapping up 2017 on Swift by Sundell
On the 17th of February 2017 I published my very first weekly blog post - "Providing a unified Swift error API". At the time I had no idea whether anyone would want to read what I wrote, and I didn't know whether writing a new post every week was something I was going to enjoy doing either.
45 weeks later, not only am I really loving writing these posts every week, but it seems like you - the readers - are enjoying them quite a lot as well. I'm super happy and grateful for all the amazing feedback you have given me this year, and for helping me to grow this blog into something much bigger than I could ever have imagined.
Yet, we're just getting started, and I have some pretty big plans for this blog for the upcoming year. You can look forward to lots of new content, new formats and collaborations with other people in the community. But before we get there, I want to dedicate this week's post to highlighting some of the most popular posts from this year, as well as share some overarching themes and patterns that I've noticed among them.
Let's dive right in, starting with the top 5 posts of 2017! 😀
Here are the 5 posts that have been read the most times throughout the year:
State management is really hard, especially if you want to find a way that both lets you reduce the amount of mutable state in an app, and also ensure that it always has a single source of truth. In "Modelling state in Swift", we took a look at how the amount of state you keep can be reduced and simplified by using enums and rendering state changes reactively.
Every new year since 2014 has brought a new major version of Swift. This year was a bit special though, since Swift 4 didn't change nearly as many APIs as Swift 2 and 3 had done before it. One thing that did change quite a bit (especially under the hood), however, were strings. In "Exploring the new String API in Swift 4", I wanted to share my experiences diving into the new API and highlight some of its useful new capabilities.
One of the things that make me the most happy with these posts is when someone tells me that one of my posts finally helped them understand a concept they've been struggling with. "Under the hood of Futures & Promises in Swift" is definitely the post that has generated the most amount of such feedback.
Futures & Promises is one of those programming concepts that can seem unnecessarily complicated at first, but once you learn how they work they can be very powerful. I thought, what better way to fully understand how they work then to build an implementation from scratch? So that's exactly what the post is all about.
There are some APIs that we work with every single day, yet we only tend to scratch their surface. Grand Central Dispatch (GCD) is one of those APIs for most Swift developers. Just like futures & promises, GCD offers a lot more than what it may seem like at first, and once you explore some of its more powerful features you have a lot more tools at your disposal the next time you have to tackle a tricky asynchronous problem.
Every single app I've worked on has used some form of custom animations. Most of the time, using the standard
UIView.animate API to create animations using closures is totally enough, but sometimes you want to structure things a bit differently in order to gain performance or flexibility. SpriteKit can be a great tool in such situations, by letting you declaratively create animations using actions, which can be composed and easily changed.
In my talk "Creating great animations on iOS" I also spoke about how this SpriteKit-based technique can be a great tool to let designers and developers more quickly iterate on complex animations together.
One of my main goals with this blog is to continuously share learnings from many different aspects of Swift development. Whether we're talking about asynchronous programming, animations, dependency injection or testing, I want to keep presenting multiple solutions from different angles, always with real life examples.
Even though the topics very each week, it's interesting that some particular themes and patterns keep coming back in the different solutions I end up using. Let's take a closer look at a few of those from throughout the year.
One of the topics I've written the most about this year has been testing. During 2015-2016 I started getting really into testing, and this year I've been exploring many different techniques to make testing in Swift nicer & easier. It started in January with my talk "Writing Swift code with great testability", and during the year I've written 9 different posts about testing.
People often ask me if I use Test Driven Development (or TDD) when I work, to which I usually answer that I do "TDD-ish". While I don't strictly follow the red-green-refactor workflow, I love using tests to verify that my code works as expected. I always try to accompany each pull request I make with a few tests that both prove to me that my change is indeed working as expected, but also adds a "documentation of intent" for anyone reviewing my code.
Anyone who starts working with testing soon realizes that using dependency injection is key to making code easy & nice to test. During this year, we've taken a look at several dependency injection techniques (such as a factory based approach, or a simple approach using functions) - wrapping it all up in "Different flavors of dependency injection in Swift".
One common challenge with testing and dependency injection is how to deal with system classes - especially singleton-based ones. In "Testing Swift code that uses system singletons in 3 easy steps" we took a look at a technique that can give you the best of both the singleton & dependency injection worlds by abstracting some system classes out into protocols.
One of the most complicated things that we have to deal with very often when building modern apps is asynchronous operations. Not only do almost all apps rely on some form of networking, many apps need to process large amounts of data or perform operations that are too slow to run on the main thread.
So it's not very surprising that there are many different abstractions available when it comes to handling asynchronous code. I don't believe in silver bullets, and my intention is never to "sell you" on any given solution - quite the opposite! So this year we've taken a look at many different async abstractions, including futures/promises and GCD (like mentioned earlier), but also things like using tokens and how to deal with objects captured by asynchronous closures.
Avoiding shared state
Finally, one theme that has been popping up quite a lot during the year is how to avoid introducing shared state in an app. As developers on Apple's platforms, we've gotten quite used to patterns such as using singletons. However, like we took a look at in "Avoiding singletons in Swift", there are many situations in which using an alternative approach to singletons can help us achieve a nicer architecture by reducing the amount of shared state in an app.
Along the same lines, in "Using the factory pattern to avoid shared state in Swift" we took a look at how using the factory pattern can be a great help when wanting to avoid shared state. By always creating separate instances of objects you often end up in a more predictable and easier to test situation.
Whether you're a first time reader or someone who has read every single one of my posts, I hope you enjoyed this wrap up. The next milestone ahead is when this blog turns one year old - on the 17th of February 2018, a day that I have big plans for 😉. I 'll keep writing new posts weekly until then and hope you'll stay along for the ride.
As always, you are more than welcome to either leave a comment below or ping me on Twitter @johnsundell (either publicly or via DM) with questions or feedback.
Thanks a lot for reading happy new year! 🚀