Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should protocol/implementation pairs be adjusted for the Swift API design guidelines?

Tags:

In the new Swift API design guidelines, the commonly-used Type suffix for protocols is being dropped. While this is easy to do for protocols that are stand-alone (SequenceType becomes Sequence), I'm not sure how to update my APIs in which a protocol provides the base for an implementation. Here's some examples from popular frameworks:

  • The Result µframework provides Result, a concrete success/fail enumeration, and ResultType, a generic base protocol for a success/fail type, to which Result conforms.
  • ReactiveCocoa's main types are Signal and SignalProducer, which are backed by SignalType and SignalProducerType.

In both cases, much of the implementation is in extensions of the protocols, allowing extensions to use the full power of type constraints, and allowing the implementations to be generic. This is different from the case of protocols with AnySequence-style type-erasing types: you aren't really expected to implement these protocols on your own, or unify disparate types.

like image 399
JHZ Avatar asked Apr 28 '16 14:04

JHZ


People also ask

How many protocols can a Swift class adopt?

Swift 4 allows multiple protocols to be called at once with the help of protocol composition.

What is protocol composition in Swift?

Protocol composition is the process of combining multiple protocols into a single protocol. You can think of it as multiple inheritance. With protocol DoSomething , below, class HasSomethingToDo is able to do whatShouldBeDone and anotherThingToBeDone . print("I did Something!")

What is protocol and how do you implement it?

A protocol defines a blueprint of methods, properties, and other requirements that suit a particular task or piece of functionality. The protocol can then be adopted by a class, structure, or enumeration to provide an actual implementation of those requirements.

How do I add a protocol in Swift?

To create a protocol, use the protocol keyword followed by the name you want and defined by the curly braces. Protocols can be of 2 types: read-only/read-write. Read-only means you can only get the variable, but you cannot set it. Read-write means you can both set and get properties.


1 Answers

I would advise using the suffix Protocol. This is consistent with how the standard library have stripped the Type suffix from protocols, as stated in SE-0006:

On high level, the changes can be summarized as follows.

  • Strip Type suffix from protocol names. In a few special cases this means adding a Protocol suffix to get out of the way of type names that are primary (though most of these we expect to be obsoleted by Swift 3 language features).

For example, GeneratorType was renamed to IteratorProtocol.

And, for example, is also how both Result & ReactiveSwift have updated their APIs for Swift 3. ResultType was renamed to ResultProtocol (in this commit), and SignalType was renamed to SignalProtocol, and SignalProducerType was renamed to SignalProducerProtocol (in this commit).

Although it's worth noting that in a vast majority of these cases, such protocols only exist as a workaround for the lack of parameterised extensions.

For example, we cannot currently say:

struct SomeGenericThing<T> {     var value: T }  extension <T> Array where Element == SomeGenericThing<T>, T : Comparable {  } 

But introducing a protocol allows us to realise the generic placeholder(s) as associated type(s), which we can then use in constraints:

protocol SomeGenericThingProtocol {     associatedtype T     var value: T { get set } }  struct SomeGenericThing<T> : SomeGenericThingProtocol {     var value: T }  extension Array where Element : SomeGenericThingProtocol, Element.T : Comparable {     // ... } 

Therefore once parameterised extensions are supported, we'll be able to do away with such protocols.

like image 126
Hamish Avatar answered Sep 28 '22 10:09

Hamish