Delegate implementation using generic protocol in Swift

I am trying to create a delegate protocol that implements a function that passes a generic type array. I've tried several combinations, but none of them seemed to do the trick.

This is the most approximate thing I have come to. This is the protocol:

     protocol APIControllerProtocol {

          typealias T

          func didReceiveAPIResults(results: [T])
     }

      

And this is the object-divider:

    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 gets this error: "Album is not converting to UT"

Album is a model object used to return results.

What am I doing wrong?

EDIT:

Following Mike S.'s advice , I made the protocol method a didReceiveAPIResults

generic function and specified what T

is in the delegate. However, when getting and assigning an argument of type T to a property in a delete, I get an 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"
    }
}

      

+3


source to share


1 answer


Your declaration didReceiveAPIResults

in APIControllerProtocol

must be a generic function, so that the generic type T

is passed along with it correctly.

protocol APIControllerProtocol {
    typealias T

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

      

Note. ... This means that your delegate definition should define that T

:

class TestDelegate: APIControllerProtocol {
    typealias T = Album

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

      


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



The real problem is that the compiler has trouble agreeing on something that U.T

has no ambiguity. It's actually quite easy to fix this, we just need to define it more precisely (note the sentence where

in the definition APIController

):

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

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

      

Note. I removed <T>

which I added to the function in the protocol earlier; which are no longer needed and will eventually cause problems.

With this, the class TestDelegate

works as expected (you don't need it anymore typealias

):

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

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

      

+1


source







All Articles