Posts Tagged ‘Cancellable’

Swift Property Wrapper for Cancellable

Saturday, July 4th, 2020

With SwiftUI Apple developed a new and modern way to realize user interfaces for apps. It’s faszinating how the language Swift itself with new features and all the frameworks perfectly fit together to form the capabilities of SwiftUI as a whole. One important piece of that puzzle is the Combine framework that provides a kind of “reactive” API. If you write view model code for SwiftUI, you regulary have to deal with Cancellables and you end up with the following principle over and over again:

class Someclass : ObservableObject {

    private var someCancellable: AnyCancellable? {
        didSet {
            oldValue?.cancel()
        }
    }

    private var anotherCancellable: AnyCancellable? {
        didSet {
            oldValue?.cancel()
        }
    }

    deinit {
        self.someCancellable?.cancel()
        self.anotherCancellable?.cancel()
    }
}

This is a perfect example to make use of a Property Wrapper! To be honest, I am wondering why Apple does not provide this out of the box. Property Wrappers are a way in Swift to define a customized behaviour for properties. Here’s my solution to improve and automate the repetitive code from above:

import Combine

@propertyWrapper
class AutoCancel<Value> where Value: Cancellable {
    var wrappedValue: Value? {
        didSet {
            // cancel the old Cancellable whenever a new is set:
            oldValue?.cancel()
        }
    }

    deinit {
        // cancel the Cancellable on deinit
        self.wrappedValue?.cancel()
    }
}

It’s short and easy, but has a huge impact: Now you can replace the initial verbose code from above with the following:

class Someclass : ObservableObject {
    @AutoCancel private var someCancellable: AnyCancellable?
    @AutoCancel private var anotherCancellable: AnyCancellable?
}

That’s it! The code size reduced dramatically and it is much easier to type and to read, and it is also less error-prone because you don’t have to think about cancelling these properties in the deinit block anymore.

Have fun and happy coding!