iosswiftobjective-coption-set

Accessing Swift OptionSetType in Objective-C


In my Swift class, I have an OptionSetType defined for fulfillment options.

struct FulfillmentOption : OptionSetType {
    let rawValue: Int
    
    static let Pickup = FulfillmentOption(rawValue: 1 << 0)
    static let Shipping = FulfillmentOption(rawValue: 1 << 1)
    static let UserShipping = FulfillmentOption(rawValue: 1 << 2)
}

I then create a variable to add/remove and read options. This works as expected.

 var options: FulfillmentOption = []
 options.insert(FulfillmentOption.Pickup)
 options.contains(FulfillmentOption.Pickup)

However I need to access the options variable from one of my Objective-C classes. Since OptionSetType is not defined in Objective-C, the variable is not visible to any of my Objective-C classes.

What is the best way for me to expose this to Objective-C? Should I stop using OptionSetType altogether?

I've considered doing creating public and private variables like this to convert between the two. I don't love this, but it's the best I've come up with thus far.

private var _options: FulfillmentOptions = []
private var options: UInt {
  get {
    // get raw value from _options
  }
  set {
    // set raw value to _options
  }
}

Is there a more elegant way to accomplish this? I'd like to avoid writing unnecessary code.


Solution

  • Not a direct answer to your question, but as an alternative you can work the other way around. Define

    typedef NS_OPTIONS(NSInteger, FulfillmentOption) {
        FulfillmentOptionPickup = 1 << 0,
        FulfillmentOptionShipping = 1 << 1,
        FulfillmentOptionUserShipping = 1 << 2,
    };
    

    in an Objective-C header, this would be imported into Swift as

    public struct FulfillmentOption : OptionSetType {
        public init(rawValue: Int)
    
        public static var Pickup: FulfillmentOption { get }
        public static var Shipping: FulfillmentOption { get }
        public static var UserShipping: FulfillmentOption { get }
    }
    

    More Information can be found in the "Using Swift with Cocoa and Objective-C" reference:

    Swift also imports C-style enumerations marked with the NS_OPTIONS macro as a Swift option set. Option sets behave similarly to imported enumerations by truncating their prefixes to option value names.

    You’ll have access to anything within a class or protocol that’s marked with the @objc attribute as long as it’s compatible with Objective-C. This excludes Swift-only features such as those listed here:

    • ...
    • Structures defined in Swift
    • ...