Reducing Array<OptionSet> to OptionSet

Sorry to revive an old thread!

I'm running into a very similar issue and I'm not sure if there's a cleaner way to implement encoding/decoding. I have a REST api that returns options as json array, ex: "["OptionB", "OptionC"]" and I would like to form an OptionSet from it as well as re-encode to that format.

I have the following implementation that works, but requires a lot of manual updating if the supported options changes. Is there a better way to write this, or perhaps use Mirror to get the behavior I'd like?

(note: I'm very unfamiliar with swift's reflection apis. Also, please let me know if this is off-topic; I can make a new thread if that would be better.)

struct ExampleOptions: OptionSet, Codable {
    let rawValue: Int

    static let optionA = ExampleOptions(rawValue: 1 << 0)
    static let optionB = ExampleOptions(rawValue: 1 << 1)
    static let optionC = ExampleOptions(rawValue: 1 << 2)

    init(rawValue: Int) {
        self.rawValue = rawValue
    }

    init(from decoder: Decoder) throws {
        var container = try decoder.unkeyedContainer()
        var options = [ExampleOptions]()
        while !container.isAtEnd {
            let string = try container.decode(String.self)
            let option = try ExampleOptions(string: string)
            options.append(option)
        }
        let null = ExampleOptions(rawValue: 0)
        self = options.reduce(null) { return $0.union($1) }
    }

    init(string: String) throws {
        switch string {
        case "OptionA": self = .optionA
        case "OptionB": self = .optionB
        case "OptionC": self = .optionC
        default: throw NSError(domain: "ExampleOptions", code: 0, userInfo: nil) // make this more descriptive
        }
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.unkeyedContainer()
        if contains(.optionA) { try container.encode("OptionA") }
        if contains(.optionB) { try container.encode("OptionB") }
        if contains(.optionC) { try container.encode("OptionC") }
    }
}