drewg23
drewg23

Reputation: 401

Getter Setter With Type of Any Swift

Is it possible to do a getter and setter for an attribute that has a type of 'Any'

Here is my thought:

private var _valueObject: Any?
public var valueObject: Any? {
    set {
        if newValue is String {
            self._valueObject = newValue as? String
        } else if newValue is BFSignature {
            self._valueObject = newValue as? BFSignature
        }
    }

    get {
        if self._valueObject is String {
            return self._valueObject as? String
        } else if self._valueObject is BFSignature {
            return self._valueObject as? BFSignature
        } else {
            return self._valueObject
        }
    }
}

When I try to use it through out my code though I get errors stating:

Cannot compare String to type Any

Is there a way to use something like this without casting the 'valueObject' to a string whenever I need it. A way to use it and it already knows its a 'String' or 'BFSignature' instead of 'Any'.

Here is an example of the error: enter image description here I would rather it just know that cellValue is a 'String.' Instead of casting it each time I use it.

Upvotes: 0

Views: 104

Answers (2)

FruitAddict
FruitAddict

Reputation: 2032

You shouldn't use Any

In my opinion, you should make a common representation of the API call result instead of using Any. You know exactly what the API is going to return, don't you? It's either a String or something that you turn into your custom object BFSignature.

Therefore, you can make an enum to represent your API call result:

enum APIResult {
    case signature(BFASignature)
    case justString(String)
}

and use it like

private var _valueObject: APIResult?

if let stringValue = newValue as? String {
    self._valueObject = .justString(stringValue)
}
if let signatureValue = newValue as? BFSignature {
    self._valueObject = .signature(signatureValue)
}

Upvotes: 3

Grimxn
Grimxn

Reputation: 22487

If there are a fixed number of types that you need to use here, you can use an enum:

struct BFSignature {
    var a: Int
}

enum Either {
    case bfSig(BFSignature)
    case string(String)
}

var a: Either
var b: Either

a = .bfSig(BFSignature(a: 7))
b = .string("Stack Overflow")
a = b

Usage:

switch (b) {
case Either.bfSig(let signature):
    print(signature.a) // Output integeral value
case Either.string(let str):
    print(str)          //Output string value
}

Upvotes: 3

Related Questions