Pierre
Pierre

Reputation: 675

cannot invoke initializer for type float with an argument of type (Any)

I created my variable as follow

var unitTwo: Any

Then in my script I run a function which return a value of type Any.

This value can be an Int, String or a Float ex: 0, 0.0 or "00:00:00"

unitTwo = returnTextFieldType(unitOneType: unitOneType, unitTwoType: unitTwoType).two

If it is a String before adding to my record function the string will be converted to a integer. (number of seconds)

Then later I need to check for a record but in my function it has to be a Float

let newRecord = self.checkIfBetterRecord(unitTwo: Float(unitTwo), unitOne: Float(unitOne), unitTwoType: unitTwoType, unitOneType: unitOneType)

But I get

cannot invoke initializer for type float with an argument of type (Any)

I have also tried to downcast with unitTwo as! Float but my app crash too and don't let me do this.

How can I solve this ?

Thanks

Upvotes: 0

Views: 2769

Answers (1)

vadian
vadian

Reputation: 285082

As I mentioned in the comment in Swift Any is always the worst way for declaring a common type.

This is a simple example for a protocol solution in The Swift Way.

The protocol UnitTypeConvertible got one computed property unitTypeValue and provides extensions for Int, Float and String.

The benefit is that a type UnitTypeConvertible can contain one of the three types and you get always the Int value by calling unitTypeValue.

protocol UnitTypeConvertible {
    var unitTypeValue : Int { get }
}

extension Float : UnitTypeConvertible {
    var unitTypeValue : Int { return Int(self) }
}

extension Int : UnitTypeConvertible {
    var unitTypeValue : Int { return self }
}

extension String : UnitTypeConvertible {
    var unitTypeValue : Int {
        let formatter = DateFormatter()
        formatter.dateFormat = "HH:mm:ss"
        guard let date = formatter.date(from:self) else { return 0 }

        let startDate = formatter.date(from:"00:00:00")!
        return Calendar.current.dateComponents([.second], from: startDate, to: date).second!
    }
}

let time : UnitTypeConvertible = "01:23:45"
time.unitTypeValue // 5025

Now you are able to declare

var unitTwo: UnitTypeConvertible

and write

let newRecord = self.checkIfBetterRecord(unitTwo: Float(unitTwo.unitTypeValue) ...

Upvotes: 2

Related Questions