Useful to generate query items for URLComponents when build URLRequest
letparams=ParamSerializer().serialize(object: object)varcomponents=URLComponents()
components.host ="some.api"
components.path ="some/api/path/"
components.queryItems = params.map{URLQueryItem(name: $0.key, value:"\($0.value)")}- Auto infer name of param from field name, with default/snake_case or custom naming strategy
- Nil and empty array will be remove automatically
- Auto handle array (of any elements or elements that conform to
ParamConvertible) - Auto expand nested params
- Support any custom type by conforms to
ParamConvertible, or simply use an in-place custom mapper
structApiParam:ParamsContainer{@Paramsvarquery:String?=nil@Paramsvarstatus:String="active"@Params("max_result")varmaxResult:Int=10@Params("date")varlimitDate:Date?=nil@Paramsvarids:[Int]=[1,2,3]}letparams=ApiParam()letserialized=ParamSerializer().serialize(object: params)print(serialized)
// ["status": "active", "max_result": 10, "ids": "1,2,3"]extensionDate:ParamConvertible{publicvarparameterValue:Any?{ISO8601DateFormatter().string(from:self)}}letparams=ApiParam(limitDate:Date(timeIntervalSince1970:1))letserialized=ParamSerializer().serialize(object: params)print(serialized)
// [..., "date": "1970-01-01T00:00:01Z"]structApiParam:ParamsContainer{@Params(mapper:{iflet i = $0 {return i +1}else{returnnil}})varautoIncrement:Int?=nil}letparams=ApiParam(autoIncrement:100)letserialized=ParamSerializer().serialize(object: params)print(serialized)
// ["autoIncrement": 101]Note: Conversion will go through custom mapper first, if the returned value also conforms to
ParamConvertiblethen it will be converted again using theParamConvertibleimplementation.
Note: For enum with raw value, currently there's no easy way to automatically serialize its raw value. So you will still have to conform to
ParamConvertible, but you don't have to write theparameterValueimplementation.
structParams:ParamsContainer{@Paramsvarquery:String="search"varfilter:NestedParams=.init()}structNestedParams:ParamsContainer{@Paramsvarname:String="tux"}letparams=Params()letserialized=ParamSerializer().serialize(object: params)print(serialized)
// ["query": "search", "name": "tux"]structApiParam:ParamsContainer{@ParamsvarthisShouldBeSnakeCase:Int=0}letparams=ApiParam()letconfig=ParamSerializer.Config(namingStrategy:SerializerNamingStrategy.convertToSnakeCase)letserialized=ParamSerializer(config: config).serialize(object: params)print(serialized)
// ["this_should_be_snake_case": 0]- Any custom naming strategy can be done by conforming to
NamingStrategy
classUppercaseNamingStrategy:NamingStrategy{publicfunc name(from fieldName:String)->String{return fieldName.uppercased()}}letparams=ApiParam()letconfig=ParamSerializer.Config(namingStrategy:UppercaseNamingStrategy())letserialized=ParamSerializer(config: config).serialize(object: params)print(serialized)
// ["THISSHOULDBESNAKECASE": 0]