I am trying to generalise a functions for different types of objects that does the same things (retrieves a value from the objects using a keyPath).

class GenericOutputParameter<Type>: Equatable    {

    // Single Line Parameter for the Deal parameters


    var path: WritableKeyPathApplicator<Type>
    var label: String
    var value: Any?         // THIS IS OPTIONAL
    var format: Int
    var columnID: String
    var order: Int

    init(path: WritableKeyPathApplicator<Type>, label: String, value: Any?, format: Int, order: Int, columnID: String)  {

        self.path = path
        self.label = label
        self.value = value
        self.format = format
        self.order = order
        self.columnID = columnID
    }
 }

protocol haveOutputs {

    associatedtype containerType

    var dictionary: [String : (path: WritableKeyPathApplicator<containerType>,label: String, value: Any, format: Int, order: Int)] { get set }
    var outputs: [GenericOutputParameter<containerType>] { get set }

    }



func fillOutputs<T: haveOutputs>(container: inout T)   {

    container.outputs.removeAll()

    for (columnID, valueTuple) in container.dictionary {

        container.outputs.append(GenericOutputParameter(path: valueTuple.path, label: valueTuple.label, value: valueTuple.path.retrieve(from: container), format: valueTuple.format,order: valueTuple.order, columnID: columnID))
        }


    container.outputs.sort(by: { $0.order < $1.order })

    }   // END OF FILLOUTPUTS

I am using associatedType in the protocol as each object has its own different dictionary.

The function fillOutputs(container: inout T) retrieves the value from the object for the parameter specified by the key paths and appends it to an array.

I am getting an error in the container.outputs.append line towards the end of the code, as follows: Cannot invoke 'retrieve' with an argument list of type '(from: T)'. This refers to retrieve(from: container). Before attempting to generalise, this function was a method of each object (container) and using retrieve(from: self) worked.

For reference, the retrieve method is part of another generic function:

class WritableKeyPathApplicator<Type> {

    private let applicator: (Type, Any) -> Type
    private let retriever: (Type) -> Any

    init<ValueType>(_ keyPath: WritableKeyPath<Type, ValueType>) {

        applicator = {

            ...

            }


        retriever = {
            ...

            }

        }


    func apply(value: Any, to: Type) -> Type {
        return applicator(to, value)
        }


    func retrieve(from: Type)   -> Any  {
        return retriever(from)
        }

}

Given I am not an expert on Swift nor fully comprehend protocols, I may have lost myself in a glass of water and I would appreciate any thought/help. Thanks

0

There are 0 best solutions below