In addition to the enum types already defined, we will further define an enum type for each of the API endpoints. However, this enum type is going to pack a bigger punch. Firstly, it will define two convenience functions: one for adding query paraemter values to the API request's url string, and another for obtain the set of filteres available for a specific endpoint, since each endpoint will have different filters. In other words, the latter helper function will be crucial for validating, from the programmer's point of view, the query string that will be used to build the url request. Secondly, it will have a nested enum type for filter parameteres that can be used to limit the results obtained in the JSON response. The nested enum type furthermore will have associated values for each of its cases, so that we associate parameter values with each of the filter parameter types. Another interesting aspect of this associated enum is that we will make it conform to the Hashable protocol so that we can use it to generate a set, which will be important for validating the filters used to create our url query strings. This way we can take advantage of an enum's associated values, a really cool feature in Swift in my view, all the while maintaining the uniqueness of each enum case so that it can be used as set elements or dictionary keys. The nested enum type will also define a convenience function for building the portion of the url query string that corresponds to the filter parameter.

    
enum OxfordAPIEndpoint: String{
    
    case entries, inflections, translations, wordlist
    
    enum OxfordAPIFilter: Hashable{
        
        var hashValue: Int{
            switch self {
            case .definitions( _):
                return 0
            case .domains( _):
                return 1
            case .etymologies( _):
                return 2
            case .examples( _):
                return 3
            case .grammaticalFeatures( _):
                return 4
            case .lexicalCategory( _):
                return 5
            case .pronunciations( _):
                return 6
            case .regions( _):
                return 7
            case .registers( _):
                return 8
            case .translations( _):
                return 9
            case .variantForms( _):
                return 10
                
            }
        }
        
        static func ==(lhs: OxfordAPIEndpoint.OxfordAPIFilter, rhs: OxfordAPIEndpoint.OxfordAPIFilter) -> Bool {
            return lhs.hashValue == rhs.hashValue
        }
        
        
        func getDebugName() -> String {
            switch self {
            case .domains(_):
                return "domains"
            case .lexicalCategory(_):
                return "lexicalCategory"
            case .regions(_):
                return "regions"
            case .registers(_):
                return "registers"
            case .translations(_):
                return "translations"
            case .definitions(_):
                return "definitions"
            case .etymologies(_):
                return "etymologies"
            case .examples(_):
                return "examples"
            case .grammaticalFeatures(_):
                return "grammaticalFeatures"
            case .pronunciations(_):
                return "pronunciations"
            case .variantForms(_):
                return "variantForms"
            }
        }
        
        case domains([String])
        case lexicalCategory([String])
        case regions([String])
        case registers([String])
        case translations([String])
        case definitions([String])
        case etymologies([String])
        case examples([String])
        case grammaticalFeatures([String])
        case pronunciations([String])
        case variantForms([String])
        
        func getQueryParameterString(isLastQueryParameter: Bool ) -> String {
            
            var queryString: String 
            
            switch self {
            case .lexicalCategory(let parameterValues):
                queryString = "lexicalCategory="
                queryString = parameterValues.reduce(queryString, {$0.appending("\($1),")})
                queryString.removeLast()
                break
            case .grammaticalFeatures(let parameterValues):
                queryString = "grammaticalFeatures="
                queryString = parameterValues.reduce(queryString, {$0.appending("\($1),")})
                queryString.removeLast()
                break
            case .regions(let parameterValues):
                queryString = "regions="
                queryString = parameterValues.reduce(queryString, {$0.appending("\($1),")})
                queryString.removeLast()
                break
            case .domains(let parameterValues):
                queryString = "domains="
                queryString = parameterValues.reduce(queryString, {$0.appending("\($1),")})
                queryString.removeLast()
                break
            case .registers(let parameterValues):
                queryString = "registers="
                queryString = parameterValues.reduce(queryString, {$0.appending("\($1),")})
                queryString.removeLast()
                break
            case .definitions(let parameterValues):
                queryString = "definitions="
                queryString = parameterValues.reduce(queryString, {$0.appending("\($1),")})
                queryString.removeLast()
                break
            case .etymologies(let parameterValues):
                queryString = "etymologies="
                queryString = parameterValues.reduce(queryString, {$0.appending("\($1),")})
                queryString.removeLast()
                break
            case .pronunciations(let parameterValues):
                queryString = "pronunciations="
                queryString = parameterValues.reduce(queryString, {$0.appending("\($1),")})
                queryString.removeLast()
                break
            case .variantForms(let parameterValues):
                queryString = "variantForms="
                queryString = parameterValues.reduce(queryString, {$0.appending("\($1),")})
                queryString.removeLast()
                break
            default:
                queryString = String()
            }
            
            
            if(!isLastQueryParameter){
                queryString = queryString.appending(";")
            }
            
            return queryString
        }
    }
    
    
    private func addParameterValues(parameterValues: [String ], toQueryString queryString: inout String ){
        queryString = parameterValues.reduce(queryString, {$0.appending("\($1),")})
        queryString.removeLast()
    }
    
   
    
    func getAvailableFilters() -> Set<OxfordAPIFilter >{
        switch self {
        case .entries:
            return Set([.definitions([]),.domains([]),.etymologies([]),.examples([]),.grammaticalFeatures([]),.lexicalCategory([]),
                       .pronunciations([]),.regions([]),.registers([]), .variantForms([])])
        case .inflections:
            return Set([.grammaticalFeatures([]),.lexicalCategory([])])
        case .translations:
            return Set([])
        case .wordlist:
            return Set([ .domains([]),.lexicalCategory([]),.regions([]),.registers([]),.translations([])])
        }
    }
}


To continue, please click here

If you feel confused or are having trouble following, you can go back to the previous page or back to the table of contents table of contents.