Matthew Palmer Top Articles Vanilla Rocket

Optional Computed Properties in Swift Protocols

You might want to declare an optional property when developing your Swift protocol, but not want to go full @objc since then you couldn’t use structs. Previously, this hasn’t been possible. Here’s one way I’ve been using to work around this.

You have your protocol, with one required property that all conforming types must have, and one that they can optionally include

protocol SomeProtocol {
    var required: String { get }
    var optional: String? { get }
}

Then, you use a protocol extension to implement that optional computed property for all conforming types

extension SomeProtocol {
    var optional: String? { return nil }
}

Whenever a conforming type wants to use that optional property, if it’s set, it’ll be used, but if not, that’s fine as well!

So now we can have structs that can choose whether they want to implement that computed property.

struct ConformsWithoutOptional {
    let required: String
}

struct ConformsWithOptional {
    let required: String
    let optional: String?
}

One thing to note is that you can’t do optional: String in ConformsWithOptional and expect it to override the original optional: String? in other protocol extensions. You have to match the type exactly: optional: String?. That caught me out for a while.

In general, it’s probably better to break up your protocols so that users can pick and choose the things they want to implement, but this is a quick and useful trick that I haven’t seen written up anywhere else.

My apps
💅 Vanilla – hide icons from your Mac menu bar for free
🚀 Rocket – super-fast emoji shortcuts everywhere on Mac… :clap: → 👏
😄 Emoji Bullet List – easily emojify your bullet point lists (like this one!)

Jump on my email list to get sent the stuff that’s too raunchy for the blog.
(Seriously though, it’s a once-a-month update on apps I’ve built, tips for your Mac, and other relevant info.)