Home > database >  Encoding enum with int values as String
Encoding enum with int values as String

Time:12-15

I'm developing an app using bluetooth for Android and iOS using Flutter. Android and Flutter part is working already, and for iOS only small part is left. At the moment I'm having problems with sending bluetooth properties to Flutter platform. I'm read them, use int valued enum to store them and encode them with Json to sent them on EventChannel. My problem is that I want to send them in String form, for example if the property is the following: PROPERTY_WRITE = 8, it should be encoded in Json as "PROPERTY_WRITE". You can see my code below:

enum BLEProperty: UInt, Codable {
    case PROPERTY_BROADCAST = 1
    case PROPERTY_EXTENDED_PROPS = 128
    case PROPERTY_INDICATE = 32
    case PROPERTY_NOTIFY = 16
    case PROPERTY_READ = 2
    case PROPERTY_SIGNED_WRITE = 64
    case PROPERTY_WRITE = 8
    case PROPERTY_WRITE_NO_RESPONSE = 4
}

extension BLEProperty {
    private enum CodingKeys: String, CodingKey {
        case PROPERTY_BROADCAST
        case PROPERTY_EXTENDED_PROPS
        case PROPERTY_INDICATE
        case PROPERTY_NOTIFY
        case PROPERTY_READ
        case PROPERTY_SIGNED_WRITE
        case PROPERTY_WRITE
        case PROPERTY_WRITE_NO_RESPONSE
    }
    
    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        switch self {
        case .PROPERTY_BROADCAST:
            try container.encode(BLEProperty.PROPERTY_BROADCAST, forKey: .PROPERTY_BROADCAST)
        case .PROPERTY_EXTENDED_PROPS:
            try container.encode(BLEProperty.PROPERTY_EXTENDED_PROPS, forKey: .PROPERTY_EXTENDED_PROPS)
        case .PROPERTY_INDICATE:
            try container.encode(BLEProperty.PROPERTY_INDICATE, forKey: .PROPERTY_INDICATE)
        case .PROPERTY_NOTIFY:
            try container.encode(BLEProperty.PROPERTY_NOTIFY, forKey: .PROPERTY_NOTIFY)
        case .PROPERTY_READ:
            try container.encode(BLEProperty.PROPERTY_READ, forKey: .PROPERTY_READ)
        case .PROPERTY_SIGNED_WRITE:
            try container.encode(BLEProperty.PROPERTY_SIGNED_WRITE, forKey: .PROPERTY_SIGNED_WRITE)
        case .PROPERTY_WRITE:
            try container.encode(BLEProperty.PROPERTY_WRITE, forKey: .PROPERTY_WRITE)
        case .PROPERTY_WRITE_NO_RESPONSE:
            try container.encode(BLEProperty.PROPERTY_WRITE_NO_RESPONSE, forKey: .PROPERTY_WRITE_NO_RESPONSE)
        }
    }
}

CodePudding user response:

You can add a computed property that returns the name of the enum case and then the encode(to:) function becomes much simpler

extension BLEProperty {
    var propertyName: String {
        "\(self)"
    }

    func encode(to encoder: Encoder) throws {
        var container = encoder.singleValueContainer()
        try container.encode(self.propertyName)
    }
}

Example

let properties: [BLEProperty] = [.PROPERTY_READ, .PROPERTY_BROADCAST]

do {
    let data = try JSONEncoder().encode(properties)
    if let string = String(data: data, encoding: .utf8) { print(string) }
} catch {
    print(error)
}

["PROPERTY_READ","PROPERTY_BROADCAST"]

  • Related