Blog

Latest Post

Swift Tip: Non-Empty Optionals

In our Swift Talk backend, we need to display some information that comes from a third-party API. For example, we receive the following data:

struct BillingInfo {
    var name: String
    var vatNumber: String?
}

Here’s a simplified computed property that displays the data:

extension BillingInfo {
    var lines: [String] {
        return [
            "Name: \(name)",
            vatNumber.map { number in
                "Your VAT Number is: \(number)"
            } ?? "No VAT Number."
        ]
    }
}

Note that in the cases where we don’t have a VAT number, we display a different text. Unfortunately, sometimes the API we work with also returns an empty VAT number. As a first try, we dealt with it like this:

return [
    "Name: \(name)",
    vatNumber.map { number in
        number.isEmpty ? "No VAT Number." : "Your VAT Number is: \(number)"
    } ?? "No VAT Number."
]

Of course, the duplication isn’t very nice, so we tried another approach:

return [
    "Name: \(name)",
    vatNumber?.isEmpty == false ? "Your VAT Number is: \(vatNumber!)" : "No VAT Number."
]

Unfortunately, now we have a force-unwrap, which we usually try to avoid. Another variant would be to use an if let, and pull out the formatted VAT string into a variable:

let vatString: String
if let number = vatNumber, !number.isEmpty {
    vatString = "Your VAT Number is: \(number)"
} else {
    vatString = "No VAT Number."
}

return [
    "Name: \(name)",
    vatString
]

The if let variant is safe, and has no duplication, but it involves quite a bit more code. The nice thing about the other two approaches was that the transformations were very local: they happened at the point of usage.

Even though it’s a very minor piece of code, we didn’t really like any of the solutions above. Instead, we wrote a helper that solves this in a more general way:

extension Optional where Wrapped: Collection {
    var nonEmpty: Wrapped? {
        return self?.isEmpty == true ? nil : self
    }
}

The nonEmpty property returns nil when the collection within the optional is empty. This allows us to collapse both checks (for nil and for isEmpty) into one:

return [
    "Name: \(name)",
    vatNumber.nonEmpty.map { "Your VAT Number is: \($0)" } ?? "No VAT Number."
]

We’re almost certain that we aren’t the first to come up with this solution, but if you haven’t seen it yet, we figured it might still be useful.

Our Server-Side Swift Collection covers a range of related topics. We’ll be talking more about our backend rewrite soon.

To support our work, please subscribe, or give a gift.

Previous Posts

Swift Tip: Atomic Variables โ€” Part 2

In the last Swift Tip of 2018 we showed you a simple wrapper that provides synchronized access to properties. You sent us a lot of feedback โ€”ย thank you!ย In part two we’ll offer a little more explanation, and show some alternatives.

Here’s the Atomic wrapper from the previous post:

final class Atomic<A> {
    private let queue = DispatchQueue(label: "Atomic serial queue")
    private var _value: A

    init(_ value: A) {
        self._value = value
    }

    var value: A {
        get { return queue.sync { self._value } }
    }

    func mutate(_ transform: (inout A) -> ()) {
        queue.sync { transform(&self._value) }
    }
}

We’re using a serial dispatch queue to synchronize access to the private _value property and provide a thread-safe public API exposing the read-only value property and the mutate method.

We wrote this wrapper for our specific use case. In the backend for Swift Talk we have some global properties, which store static data loaded from a Github repository. Many parts of the app read these properties to render pages. Perhaps twice a week something in the static data changes, and when it does, we reload it from Github and store the new data in these global properties.

We had to be sure to avoid race conditions, where read and write access to one of these global properties would occur simultaneously โ€” however unlikely this is in our scenario. There is practically zero contention on our synchronized properties, and even if we hit the unlikely case of a simultaneous access, performance is irrelevant. Given this context, we wrote the wrapper above as the simplest possible solution. We regularly optimize for simple code, not for the highest possible performance, or the most general solution.

That being said, let’s look at some of the suggestions we received.

First, we could make mutation occur asynchronously. This has the potential advantage of not blocking the caller in case the property is contended, with the disadvantage that the value might not have changed yet after mutate finishes:

func mutate(_ transform: (inout A) -> ()) {
    queue.async { transform(&self._value) }
}

If there is a lot of contention from reading the property, we could use a concurrent queue to allow multiple reads simultaneously, while making sure that write accesses are exclusive (as suggested by @unger and @_ok1a):

final class Atomic<A> {
    private let queue = DispatchQueue(label: "Atomic serial queue", attributes: .concurrent)

    // ...

    func mutate(_ transform: (inout A) -> ()) {
        queue.sync(flags: .barrier) { transform(&self._value) }
    }
}

If performance is absolutely critical, we could choose to use os_unfair_lock instead of a dispatch queue (as suggested by @jasongregori).

As always, there are many ways to solve a particular problem, each with their own set of tradeoffs. For our application we chose to keep our code unchanged: it’s the simplest solution for our problem, and it’s more than fast enough.

In a similar manner, we suggest that you make sure you really need these kinds of optimization before you apply them, and that you fully understand the behavior of the locking API you’re using (this remains true for our original implementation).

We always try to choose the simplest solution for the task at hand, and simple here means simple for us: we need to feel we understand our code.

In Swift Talk 42, we implement thread safety for a type in a reactive framework; a specific case that helps us learn generic solutions that can be used in many other places.

If you’re interested in server-side Swift programming, we cover a range of related topics in our Server-Side Swift Collection. We’ll be talking more about our backend rewrite soon!

If you’d like to support us, you can subscribe, or give a gift. ๐Ÿ™

Looking Back, Looking Forward

2018 01 02 new year

๐Ÿ‘€ Looking Back

Happy New Year! ๐Ÿฅณ

In something approaching a tradition, we’d like to take a moment and reflect on the past year. Several milestones stand out, with Swift Talk crossing into double digits and our weekly Swift Tip reaching its first anniversary, but let’s start with perhaps our most major work: the publishing of a new book.

๐Ÿ“— App Architecture

Conceived in a “hallway track” conversation in early 2017, after a long gestation period and several rewrites, our latest book App Architecture finally joined the world in May. Co-written with Matt Gallagher, it takes a single app and fully implements it in five design patterns. For the first time, we wrote the book with video in mind, filming an integrated series with Matt to accompany it. We even recorded weekly video Q&As for our Early Access readers, who asked some great questions. We’re glad to say you liked it! Many of you chose the full Ebook + Videos bundle, and we’re really excited about the future of this format.

It wasn’t the only birth in 2018. Shortly before publishing Chris became a dad. Early Access readers heard the good news in a short introduction to their weekly Q&A.

๐Ÿ“บ Swift Talk

Our subscription video series, Swift Talk, crossed the 100th episode threshold, and we celebrated with our first live Q&A. We made 51 episodes in 2018, bringing us to over 130 episodes!

Not resting on our laurels, we also ported the Swift Talk backend to Swift โ€”ย you’ll hear more about this soon. ๐Ÿ˜‰ The performance (both in terms of speed as well as memory) has increased hugely. For us, it’s much more fun to work in Swift, and the increased speed and safety helps us introduce new features faster, gift subscriptions being the first example. ๐ŸŽ

๐Ÿ“บ Most Watched

It’s always interesting, and sometimes surprising, to see which episodes you watch the most.

The most watched episode in 2018 was… Tiny Networking Library, our first ever! This year, for our first public episode, Tiny Networking Library Revisited, we return to 2016 and update the library using more contemporary techniques.

Looking at episodes released in the last year, here are the top five:

๐Ÿฅ‡ Sharing State between View Controllers in MVC

๐Ÿฅˆ Refactoring Imperative Layout Code

๐Ÿฅ‰ Extensible Libraries 1: Enums vs Classes with special guest Brandon Kase

๐Ÿ™Œ Building a Form Library: Introduction

๐Ÿ‘ Extensible Libraries 2: Protocol Composition

With the number of episodes increasing, we introduced Swift Talk Collections in 2017 to help you navigate by topic. One year on, here are the top three:

๐Ÿ› Architecture

๐Ÿฆ Swift, the Language

๐ŸŒŽ Networking

Thanks to everyone who watched! A very special thank you to our subscribers, you made it all possible.

If you’d like to support us, you’d be very welcome!

๐Ÿ“š Most Read

2018 was the year we launched Swift Tip, our series of compact weekly posts highlighting interesting or useful techniques. Many of the techniques emerged from Swift Talk, our other weekly series. Of the 43 tips published, February’s String to Data and Back was by far the most popular, and you’ll find many more useful techniques in the archive.

For those long form readers, App Architecture was our most popular book. Once again, our sincerest thanks to everyone who took part in the pre-release, your feedback was invaluable.

Advanced Swift, co-written with Ole Begemann and Ben Cohen, follows as a close second.

๐Ÿ”ฎ Looking Forward

This is the year of Swift 5, which has a whole bunch of improvements. We’re quite happy that the language has mostly stabilized, as most improvements won’t affect existing code. We’ll be updating all our books to match.

We have a full year of Swift Talk ahead too, with some exciting ideas about how to bring the experience closer to our audience. Stay tuned!

We’d like to thank everyone we’ve worked with, both directly and indirectly. Special thanks go to Brandon, Degrau, Juul, Morgan, Matt, Natalye, Ole, Paulo, Quinten, Wouter, and Wei. We couldn’t do it without you.

Good luck with your projects! We can’t wait to get started.

Best from Berlin,

Florian and Chris

Swift Tip: Atomic Variables

In our Swift Talk backend, we load static data when our app launches. All episodes and collections are loaded from a git repository, before being transformed and made ready to use. When the repository changes we receive a webhook, which we use to reload the data.

If we declared our episodes and collections as regular properties, we might run into a race condition: we could be simultaneously reading a property on one thread while writing to it on another. Like many threading bugs, this is something that will almost never happen, but when it does it is hard to track down, and can crash our app.

To remedy this, we use an Atomic class that uses GCD queues to provide synchronized access to a variable.

final class Atomic<A> {
    private let queue = DispatchQueue(label: "Atomic serial queue")
    private var _value: A
    init(_ value: A) {
        self._value = value
    }

    var value: A {
        return queue.sync { self._value }
    }
}

Of course, just being able to read a value is uninteresting, we need a way modify it as well. It is very tempting to change value to be get set, like this:

var value: A {
    get {
        return queue.sync { self._value }
    }
    set { // BAD IDEA
        queue.sync {
            self._value = newValue
        }
    }
}

However, this is a very bad idea. Let’s look at the following example to see why:

var x = Atomic<Int>(5)
x.value += 1

While it looks like the increment is an atomic operation, it isn’t. First, the value is fetched (atomically), then it’s incremented, then it’s written back (atomically). Although the atomic read and write accesses can no longer crash our app, we can end up with the wrong value in the value property if another thread modifies it in between read and write.

In Swift 5, we might be able to solve this using _modify (also see Ben Cohen‘s Functional Swift talk, ’Fast Safe Mutable State‘). However, until that’s possible we need a different solution.

Instead, we add a mutate method that atomically mutates the underlying variable:

final class Atomic<A> {
    private let queue = DispatchQueue(label: "Atomic serial queue")
    private var _value: A
    init(_ value: A) {
        self._value = value
    }

    var value: A {
        get {
            return queue.sync { self._value }
        }
    }

    func mutate(_ transform: (inout A) -> ()) {
        queue.sync {
            transform(&self._value)
        }
    }
}

This makes the call site a little more verbose, but that’s a small price to pay for thread-safety:

let x = Atomic<Int>(5)
x.mutate { $0 += 1 }

On Swift Talk, we have covered a number of topics around server-side Swift programming, which you can find in our Server-Side Swift Collection.

In Swift Talk Episode 42, we implement thread safety for a type in a reactive framework; a specific case that helps us learn generic solutions that can be used in many other places.

If you’d like to support us, you can subscribe, or give a subscription as a gift. ๐ŸŽ

Swift Tip: Stable APIs on the Server

In our Swift Talk backend, one of the endpoints we have to support is a JSON API. Other apps, such as our main website and our unreleased tvOS app, expect the JSON to be in a specific format. Importantly, this format shouldn’t change over time (except for additive changes), because that would break existing clients.

The easiest way to generate JSON in Swift is by using Codable. In our backend, we have an Episode struct that represents a single episode. However, the struct doesn’t quite match the JSON we want to generate: it has some private data that we don’t want to expose publicly, and it has fields that are named differently.

Rather than changing our Episode struct to match the JSON API, we took a different approach. In our view file, we created a second episode struct. This struct has exactly the fields we want to expose, in the format the JSON API expects:

fileprivate struct EpisodeView: Codable {
    var number: Int
    var title: String
    var synopsis: String
    var url: URL
    var small_poster_url: URL
    var media_duration: Int
    var released_at: Date
    var collection: String
    var subscription_only: Bool
}

We then created an initializer on EpisodeView that takes an Episode as the input. It can be a bit tedious to copy properties over, but there are some big advantages.

First of all, the EpisodeView struct serves as documentation for our API. We know that this is exactly the format we will get. Secondly, we don’t have to customize any JSON generation, but instead rely on Codable to generate JSON. Thirdly, we’re now free to change our internal implementation of Episode. If we change the name of a field, or the type, the compiler will make sure that we also change the conversion from Episode into EpisodeView.

On Swift Talk, we have covered a number of topics around server-side Swift programming, which are all in our Server-Side Swift Collection.

If you’d like to support us, you can subscribe, or give a subscription as a gift.