Tricky Swift Extension attributes that you need to know

Extension

Fact 1: Extension in swift does not like stored property

If you try to declare a stored property, either a constant or a variable, the compiler will complain like what it does in below

To remove this complaint and make the compiler happy, you can add static in front of this constant declaration. Now, this constant becomes a type property in swift.

Note: Not only Class Extension, but also Struct Extension, enumeration Extension, and Enum itself, they all the same as in do not support stored property.

What to do:

Something that you can do to work around this scenario is:

<1> As I mentioned earlier, add static in front of the property declaration.

<2> Add computed instance properties and computed type properties

Fact 2: Extension from a Protocol, be careful the method dispatching trap

When we deal with method dispatch in swift, often, we are talking about these two types of method dispatching:

  • Table Dispatch
  • Message Dispatch(Tree Dispatch)

Now, have a look at the following code and have a guess, what might be the outcome printed out.

Not sure if your guess is correct, but this is what the console printed out for me:

Before you started wondering why, please modify the protocol to be like this

protocol IamProtocol {func method()}

Now run and see what comes out from the print command.

Yes, it is indeed

I am in struct

After this hassling around, the why turns out to be quite simple, because invoking the Extension method in swift is static dispatch.

Like what we have observed here if the original place, which is where the protocol is declared does not contain the method signature, invoke method means the one inside the protocol’s Extension.

This becomes immediately important, especially when you wanted to unit test behaviour that involves executing the Extension method.

A scenario like, you have a mock class that conforms to a protocol. The Extension method deals with complicated logic to produce a value, let’s say a Boolean. The unit test needs to modify the method because the unit test does not care about the logic in the Extension method, but it only needs a Boolean value to continue the test.

However, without a method signature declared in the protocol, the unit test will always go through the Extension method and executes the real production code, despite in the unit test, you’ve set up a return value for the unit test.

This might cause your unit test flaky, especially when the logic is some sort of heavy lifting, like a networking request.

That is all for today 🎆

I plan to keep on digging out more tricky facts in swift, please thumb up if you like this article.

Happy coding :)

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store