Swift is a unique language that has some revolutionary ideas. One of which is protocol conformance extension. This concept allows you to take an existing type and force it to adopt another protocol it never knew it existed before.
For example, in the below code I am grouping two types together that were previously unrelated: “CLKComplicationTemplateCircularSmallRingText” and “CLKComplicationTemplateModularSmallRingText”. They neither inherit an ancestor nor share a protocol in “ClockKit’s” source code, even though they both have a `fillFraction` property:
protocol CLKComplicationTemplateRingable { var fillFraction: Float { get set } } extension CLKComplicationTemplateCircularSmallRingText: CLKComplicationTemplateRingable { } extension CLKComplicationTemplateModularSmallRingText: CLKComplicationTemplateRingable { } class ComplicationController: NSObject, CLKComplicationDataSource { func getPlaceholderTemplateForComplication(complication: CLKComplication, withHandler handler: (CLKComplicationTemplate?) -> Void) { var template: CLKComplicationTemplate? = nil switch complication.family { case .CircularSmall: let familyTemplate = CLKComplicationTemplateCircularSmallRingText() // Do more stuff template = familyTemplate case .ModularLarge: let familyTemplate = CLKComplicationTemplateModularLargeColumns() // Do more stuff template = familyTemplate case .ModularSmall: let familyTemplate = CLKComplicationTemplateModularSmallRingText() // Do more stuff template = familyTemplate case .UtilitarianLarge: let familyTemplate = CLKComplicationTemplateUtilitarianLargeFlat() // Do more stuff template = familyTemplate case .UtilitarianSmall: let familyTemplate = CLKComplicationTemplateUtilitarianSmallFlat() // Do more stuff template = familyTemplate } if var t = template as? CLKComplicationTemplateRingable { t.fillFraction = 0.77 } handler(template) } }
In the native “ClockKit” API, these two templates strangely did not inherit from a base class. However, I wanted to treat them the same because in my world they were similar; they both fill a ring. I simply wanted to update the `fillFraction` property in one go, but I did not want to duplicate code and apply the same logic in two switch cases.
Even though I cannot change the original “ClockKit” source code myself, I taught it new tricks by comforming to my code. First I created a protocol, called “CLKComplicationTemplateRingable” here, then extended the types I wanted by making them conform to my new protocol. Now throughout my code going forward, “CLKComplicationTemplateCircularSmallRingText” and “CLKComplicationTemplateModularSmallRingText” have something in common and can refer to them using my new protocol.
Of course, this is a simplistic example, but the implications of it is vast. I’m changing the DNA of source code that I had no control over. This contributes to the wonderful world of Protocol-Oriented Programming!
Happy Coding!!
Code can’t be compiled, Extension protocol can’t use compute property.
It does compile and using it in a real watch app :). Extension protocol’s cannot use stored properties.
Also take a closer look, there is nothing defined in the extension. That’s the interesting part – the protocol defines the structure and the extension just backfills the adoption. The type already has this property defined and naturally conforms to it.