jjackson-esristaff

Old School Enums

Blog Post created by jjackson-esristaff Employee on Jul 22, 2014

When working with the ArcGIS Runtime SDK and Swift we are occasionally reminded that the SDK was written in Objective-C. And while Swift generally does a nice job of bridging the two languages, there are some shortcomings. One of those is how Swift deals with enums.

 

For example, the enum AGSGeometryOffset type is defined in Objective-C like this:

 

typedef enum {

  AGSGeometryOffsetTypeMitered = 0,   /*!< Mietered */

  AGSGeometryOffsetTypeBevelled,      /*!< Bevelled  */

  AGSGeometryOffsetTypeRounded,       /*!< Rounded */

  AGSGeometryOffsetTypeSquare         /**  Square  */

} AGSGeometryOffsetType;

 

Swift turns that into this:

 

var AGSGeometryOffsetTypeMitered: AGSGeometryOffsetType { get }

/*!< Bevelled  */

var AGSGeometryOffsetTypeBevelled: AGSGeometryOffsetType { get }

/*!< Rounded */

var AGSGeometryOffsetTypeRounded: AGSGeometryOffsetType { get }

var AGSGeometryOffsetTypeSquare: AGSGeometryOffsetType { get } /**  Square  */

struct AGSGeometryOffsetType {

    init(_ value: UInt32)

    var value: UInt32

}

 

Note: If the Objective-C enum is defined with the NS_ENUM() macro, then Swift does a nice job of importing it; however, that's not the case for now with the ArcGIS SDK. We will be releasing an update to address this issue, but in the meantime there are some things you can do.

 

Before Beta-4, you were able to use the value property of the enum in order to do comparisons or switch statements. For example:

 

    let maneuver = someFunction()

   

    if maneuver.value == AGSGeometryOffsetTypeSquare.value {

        // do something

    }

 

But with Beta-4 which was released yesterday, that value property is no longer accessible. The error looks like this:

 

'AGSGeometryOffsetType' does not have a member named 'value'.

 

With some help from some developers on the Apple forums, I came up with this work-around. It's what I'm using in my Swift apps until we have support for the NS_ENUM() macro in the SDK. Use an extension on the enum type to introduce a new property that uses reinterpretCast to generate an integer value:

 

extension AGSGeometryOffsetType {

    var rawValue : UInt32 { get {

        var raw: UInt32 = reinterpretCast(self)

        return raw

    }}

}

 

Then use the property explicitly as before:

 

    let maneuver = someFunction()

   

    if maneuver.rawValue == AGSGeometryOffsetTypeSquare.rawValue {

        // do something

    }

 

It's no fun having to create all of those Swift extensions, but it's better than being stuck in the water until the SDK update is available.

Outcomes