Implement delegate using generic protocol in Swift

grago

I'm trying to create a delegate protocol that implements a function which passes an array of a generic type. I've tried several combinations but none of them seem to do the trick.

This is the most approximate thing i've reached to. This is the protocol:

     protocol APIControllerProtocol {

          typealias T

          func didReceiveAPIResults(results: [T])
     }

And this is the the delegator object:

    class APIController<U:APIControllerProtocol> {

         typealias ElementType = U
         var delegate: ElementType?

         init(delegate: ElementType){

             self.delegate = delegate

         }

         func getAPIResults(){

              // Perform some action before delegation
              // "results" is an Array of dictionaries got from NSJSONSerialization

              self.delegate?.didReceiveAPIResults(results.map{dict in Album(json:dict)})

         }

     }

However, the last line get this error: "Album is not convertible to U.T"

"Album" is the model object used to return the results.

What am i doing wrong?

EDIT:

Following Mike S advice, i've made the protocol method didReceiveAPIResults a generic function, and specified what T is in the delegate. However, when receiving and assigning the argument of type T to a property in the delegate, i get the error: "T is not identical to T"

class TestDelegate: APIControllerProtocol {
    typealias T = Album
    var albums:[T] = [T]()

    func didReceiveAPIResults<T>(results: [T]) {
        // ...

        self.albums = results //ERROR: "T is not identical to T"
    }
}
Mike S

Your didReceiveAPIResults declaration in APIControllerProtocol needs to be a generic function so that the generic type T is passed along to it correctly.

protocol APIControllerProtocol {
    typealias T

    func didReceiveAPIResults<T>(results: [T])
}

Note: This means your delegate definition will need to define what T is:

class TestDelegate: APIControllerProtocol {
    typealias T = Album

    func didReceiveAPIResults<T>(results: [T]) {
        // ...
    }
}

Update: While the code above does get rid of the original error, it turns out that it acts more like a workaround and doesn't really address the root of the problem.

The real issue seems to be that the compiler is having trouble reconciling what U.T is with no ambiguity. That's actually easy enough to fix though, we just need to give it a more precise definition (note the where clause in the APIController definition):

protocol APIControllerProtocol {
    typealias T
    func didReceiveAPIResults(results: [T])
}

class APIController<U:APIControllerProtocol where U.T == Album> {
    typealias ElementType = U
    // ...
}

Note: I removed the <T> that I added to the function in the protocol previously; that's not needed anymore and will end up causing problems later.

With that, the TestDelegate class works as expected (you don't even need the typealias anymore):

class TestDelegate: APIControllerProtocol {
    var albums: [Album]? = nil

    func didReceiveAPIResults(results: [Album]) {
        albums = results
    }
}

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Swift using generic in protocol

Using associatedtype in a delegate protocol for a generic type

Using Generic swift enum in a protocol

Generic Decoder for Swift using a protocol

How to use a generic protocol as a delegate?

Swift - implement protocol with generic method for different <T> types

Swift 5: Implement generic array operations on structs implementing Equatable with protocol

Swift delegate for a generic class

Implement Delegate with Closure in Swift?

iOS - Pass Data from Swift to ObjC VC using protocol and delegate

How to require a generic type implement a generic protocol using a specific type in the protocol

How to implement to a generic protocol, which has a function using the Type of associatedtype?

Swift protocol delegate returning nil

Protocol Delegate Does not Trigger Swift

Swift 2 - protocol delegate not called

Swift Error on communication Protocol/Delegate

Swift 3 Protocol and Delegate Method?

Protocol Delegate returns nil swift

Swift generic table view data source and delegate, protocol backed NSManagedObjects, cannot obtain entity attribute, runtime error

Swift Generic Protocol

Swift generic Serializable protocol

Proper way to implement a custom UIViewController interactive transition using UIViewControllerInteractiveTransitioning Delegate Protocol

How to write generic function in Swift using a protocol associatedtype

How can we implement concurrency thread using protocol in swift?

Using delegates on generic protocol

Protocol Delegate not working as expected returns nil swift

swift protocol delegate always return nil

iOS Swift - Protocol sending delegate to wrong TableViewController

Swift - UIView Delegate Protocol not returning value