Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass a Type as a parameter in Swift

I have a dictionary of objects and what I would like to do is go through the data set and return an array of objects that conform to a given protocol. I am having issues with the syntax for passing in a desired protocol:

func getObjectsThatConformTo<T>(conformance: T.Type) -> [AnyClass]{
  var returnArray: [AnyClass] = []
  for(myKey, myValue) in allCreatedObjects{
    if let conformantObject = myValue as? conformance{
      returnArray.append(conformantObject)
    }
  return returnArray
}

The error I am seeing is 'conformance' is not a type

Thank you for your help and time

like image 572
CWineland Avatar asked Jul 30 '15 17:07

CWineland


2 Answers

I think this should work:

func getObjectsThatConformToType<T>(type:T.Type) -> [T]{
    var returnArray: [T] = []
    for(myKey, myValue) in allCreatedObjects{
        if let comformantModule = myValue as? T {
            returnArray.append(comformantModule)
        }
    }
    return returnArray
}
like image 182
avismara Avatar answered Sep 27 '22 16:09

avismara


While you could write a generic-ed method that filters through an array and sees which things in the array are a given type, this problem screams for the use of filter.

Example:

var dict: [String: AnyObject] = [:]
// Populate dict with some values
let strings = dict.values.filter { return $0 is String }

Wrapped in a function that takes type:

func getObjectsThatConformTo<T>(array: [Any], conformance: T.Type) -> [T]? {
    return array.filter { return $0 is T } as? [T]
}

Explanation: Filter is a method on Array which returns a subset of the array based on a test. In this case our test is 'is the element a String?' the filter method accepts a closure with one parameter, the element to be tested, above referred to with $0.

Read up on filter here: https://www.weheartswift.com/higher-order-functions-map-filter-reduce-and-more/

like image 34
rudd Avatar answered Sep 27 '22 18:09

rudd