0

I am trying to make a protocol that has has two associated types. One of these associated types is for a delegate. When I try to use another protocol as the associated type, I get the error "Type 'HostConnectionService' does not conform to protocol 'ConnectionService'". The code I have is written below:

protocol ConnectionService: class {
    associatedtype Peer: Sharelist.Peer
    associatedtype Delegate: ConnectionServiceDelegate
    var connectedPeers: [Peer] { get }
    var delegate: Delegate? { get }
}

protocol ConnectionServiceDelegate { }

// Error
class HostConnectionService: NSObject, ConnectionService {
    typealias Peer = GuestPeer
    typealias Delegate = HostConnectionServiceDelegate

    var delegate: HostConnectionServiceDelegate?
    var connectedPeers: [GuestPeer] = []
}

protocol HostConnectionServiceDelegate: ConnectionServiceDelegate { }

When I change the line

typealias Delegate = HostConnectionServiceDelegate

to be of a non-protocol type, I no longer get an error:

struct NonProtocolConnectionServiceDelegate: ConnectionServiceDelegate { }

// No Error
class HostConnectionSertice: NSObject, ConnectionService {
    ...
    typealias Delegate = NonProtocolConnectionServiceDelegate
    ...
}

Is this a fundamental Swift limitation, or am I doing something wrong?

1 Answers1

0

Your example is too complicated to understand. I tried to simplify it.

It compiles without errors:

protocol ProtocolA {}

protocol ProtocolB {
    associatedtype SomeType
}

class SomeClass: ProtocolB {
    typealias SomeType = ProtocolA
}

let object = SomeClass()

But the following example is no longer compiled:

protocol ProtocolA {}

protocol ProtocolB {
    associatedtype SomeType: ProtocolA
}

class SomeClass: ProtocolB {
    typealias SomeType = ProtocolA
}

The error is as follows:

error: type 'SomeClass' does not conform to protocol 'ProtocolB'

note: possibly intended match 'SomeType' (aka 'ProtocolA') does not conform to 'ProtocolA'

This is because protocols don't conform to themselves

Most likely in your case it is necessary to make the class template:

protocol ProtocolA {}

protocol ProtocolB {
    associatedtype SomeType: ProtocolA
}

class SomeClass<T: ProtocolA>: ProtocolB {
    typealias SomeType = T
}

extension Int: ProtocolA {}
extension Double: ProtocolA {}

let object1 = SomeClass<Int>()
let object2 = SomeClass<Double>()
Community
  • 1
  • 1
dronpopdev
  • 797
  • 10
  • 13