0

I’m building a weather app that will provide access to multiple weather providers from which I get slightly-to-very different data sets returned. I want to make the system that handles the setting up of the data to be as generic as possible to accelerate the addition of new providers.

Firstly, I have an enum RValueUnits that consists of all possible units that values can be returned in:

enum RValueTypes { /// returned value
    case cm
    case celsius
    case decimal
    case mm
    case percentage
    case inch
    /// etc
}

Some providers, for example, may return precipitation amount in .mm, others in .cm.

What I want is for each provider to have an enum of their own listing all the properties that they return including the return type. For example:

enum DarkSkyProps: CaseIterable {
    static var allCases: [DarkSkyProps] {
        return [
            .apparentTemperature(unit: .celsius, setter: setApparentTemperature)
        ]}
    
    case apparentTemperature(unit: RValueType, setter: () throws -> Void)
}

The setter function associated with each case handles the property’s data set up. For example, it would compare the return value type from the provider with the user’s preference, and if it’s different, it will change it before setting it as the value of the associated property, for example apparentTemperature in the above case.

static func setApparentTemperature() throws {
    /// processing logic goes here
}

I have one issue and one question:

Firstly, I wanted DarkSkyProps to be CaseIterable so the setup is automatic. However, I have no idea how to call the iterated case’s associated setter function:

for property in DarkSkyProps.allCases {
  /// want to call property.setter()
}

Secondly, ideally I also want there to be enum ForecastSource such as:

enum ForecastSource {
    case DarkSky
    case Foreca
}

And for each to be associated with a Props enum (i.e. ForecastSource.DarkSky is linked to DarkSkyProps), like:

case DarkSky(props: DarkSkyProps.AllCases)

So that I then need to only write something like, for example:

var source: ForecastSource = .DarkSky
for property in source.props {
    /// want to call property.setter()
}

Is there a way?

Finally, considering what I’m aiming for, is there an actually entirely different approach that is more suitable?

Many thanks!

Barrrdi
  • 902
  • 13
  • 33
  • I don't think I would have something like RValueTypes that holds all types but rather different enums for similar types like Celsius/Fahrenheit, mm/cm/inch/..., decimal/percentage etc – Joakim Danielson Jan 04 '21 at 13:22
  • Good point, but I thought that by having different enums of similar types then that may compromise the checks in property.setter() as the type varies. But I guess not as they can just be Ints. – Barrrdi Jan 04 '21 at 13:34

0 Answers0