Swift: Making the Associated Type Parameter Readable in Protocols

I’m still getting used to Associated Types in Swift. Even though they’ve been around for a while, I first starting to understand them from this talk by @alexisgallagher.

So I was happy yesterday when I used them to sort of solve a common problem in iOS development: View Controller Data Injection with Storyboards and Segues in Swift.

I updated my blog post from yesterday, but my initial Protocol looked something like this:

Notice the thing! Since each View Controller would be injected with something specific – it could be text-based or number-based or array-based, anything! I didn’t know how to name the parameter. So thing seemed like the most fitting parameter name.

The implementation was something like this then:

I didn’t exactly like the whole thing here – it’s not that great with readability. So this morning, I though of a crazy solution for this, tried it out, and it actually worked!

Instead of using thing, I leave the parameter name blank in the protocol!

Apparently, this now let’s me name the parameter anything I want in the implementation!

Now, the implementation is super clear! The more I use associated types, the more I like them!

Enjoy the article? Join over 17,500+ Swift developers and enthusiasts who get my weekly updates.

  • Bryan Hoke

    In inject(thing: T) — which is equivalent to inject(_ thing: T)thing is just a local parameter name that has no bearing on the call-site or function name, so you could already give thing a different name in implementations of inject without the need to replace it with a wildcard. However, I do agree that inject(_: T) reads better than inject(thing: T) in the protocol declaration.

  • Jessy Catterwaul

    Natasha, you don’t need to explicitly define a typealias.

    swift

    class MyStringDependencyViewController: UIViewController, Injectable {

    private var textDependency: String!

    func inject(text: String) {

    textDependency = text

    }

    }

    class MyIntDependencyViewController: UIViewController, Injectable {

    private var numberDependency: Int!

    func inject(number: Int) {

    numberDependency = number

    }

    }

    Also, I never use T. I either give the type a real name, or use the 🃏 emoji.

    swift

    protocol Injectable {

    associatedtype Injected

    func inject(_: Injected)

    }

    • Good to know! I also fixed your code formatting with html tags (vs markdown).

    • Decided I like it without the explicit typealias better, so updated the blog post! Thanks.

  • Nick Kohrn

    So, does this work by calling the inject(text: String) method on an instance of the view controller?

    For instance, in prepareForSegue:, when you create an instance of a view controller to access a property to set, you then gain access to the property. But if the property is set a private, then you can’t access it. Is that what this is for? Call inject: on the destination view controller and passing the item to send so that that view controller can set its own private variable?

  • Heistings

    Hey, I’ve just found that, there is no need to use the _, it’s still possible to use a new parameter name when implementing a protocol:

    swift

    protocol TestProtocol {

    func method(a: String)

    }

    struct TestStruct: TestProtocol {

    func method(b: String) {

    print(b)

    }

    }

    var b: TestProtocol = TestStruct()

    b.method("hello")

  • Di

    Nice. I usually use something like this, inspired by NSCell 🙂

  • Victor Sigler

    Natasha interesting post !! But something changed and now you cannot implement the Injectable protocol without explicitly declare the argument label. So pretty much you need to update your code to:

    I tested using Swift 3.1