1

I'm working with the Persona SDK, and they return a bunch of fields encoded in a dictionary like this.

/// The types of values that can be accepted as additional inquiry fields.
public enum InquiryField {

    /// A string value
    case string(String?)

    /// An integer value
    case int(Int?)

    /// A float value
    case float(Float?)

    /// A boolean value
    case bool(Bool?)

    /// A date value (without time)
    case date(Date?)

    /// A datetime value
    case datetime(Date?)

    /// An unknown value
    case unknown
}

func inquiryComplete(inquiryId: String, status: String, fields: [String : InquiryField]) {

}

I would like to map the value in fields to my own struct where the properties will have the same name as the keys.

struct PersonaInquiryData: Codable {
    var inquiryId: String
    var status: String
    
    var nameFirst: String? // ALEXANDER J
    var nameMiddle: String?
    var nameLast: String?
    var birthdate: Date? // 1977-07-17 04:00:00 +0000
    var emailAddress: String?
    var phoneNumber: String?
    var selectedCountryCode: String? // US
    
    var addressStreet1: String? // "600 CALIFORNIA STREET"
    var addressStreet2: String?
    var addressCity: String? // SAN FRANCISCO
    var addressSubdivision: String? // CA
    var addressPostalCode: String? // 94109
    var addressCountryCode: String? // US
    
    var identificationClass: String? // dl
    var selectedIdClass: String?
    var currentGovernmentId: String?
    var identificationNumber: String? // I1234562
}

I'm not sure the best way to do this mapping. This was my best attempt, but seems like there could be a more Swifty way to do this.

func inquiryComplete(inquiryId: String, status: String, fields: [String : Persona2.InquiryField]) {
    
    var data = PersonaInquiryData(inquiryId: inquiryId, status: status)
    
    for (name, value) in fields {
        switch value {
        case .string(let string):
            switch name {
            case "nameFirst": data.nameFirst = string
            case "nameMiddle": data.nameMiddle = string
            case "nameLast": data.nameLast = string
            case "emailAddress": data.emailAddress = string
            case "phoneNumber": data.phoneNumber = string
            case "selectedCountryCode": data.selectedCountryCode = string
            case "addressStreet1": data.addressStreet1 = string
            case "addressStreet2": data.addressStreet2 = string
            case "addressCity": data.addressCity = string
            case "addressSubdivision": data.addressSubdivision = string
            case "addressPostalCode": data.addressPostalCode = string
            case "addressCountryCode": data.addressCountryCode = string
            case "identificationClass": data.identificationClass = string
            case "selectedIdClass": data.selectedIdClass = string
            case "currentGovernmentId": data.currentGovernmentId = string
            case "identificationNumber": data.identificationNumber = string
            default: break
            }
        case .date(let date):
            switch name {
            case "birthdate": data.birthdate = date
            default: break
            }
        default: break
        }
    }       
}
Berry Blue
  • 15,330
  • 18
  • 62
  • 113
  • What have you tried so far? Please edit your question and add your previous effort. Highlight exactly where you struggle and what error messages you get, if any. – burnsi Sep 22 '22 at 15:11
  • Ok, I updated my best attempt. – Berry Blue Sep 22 '22 at 21:23
  • This seems pretty much all you could do. Having a `String` key that has to map to a struct property is allways nasty. One possibility I could think of is Reflection. [Possible solution](https://stackoverflow.com/questions/31589405/using-reflection-to-set-object-properties-without-using-setvalue-forkey) – burnsi Sep 22 '22 at 22:37

0 Answers0