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