I'm using a protocol to encode the conforming structures:
protocol RequestParameters: Encodable {
}
extension RequestParameters {
func dataEncoding() -> Data? {
guard let data = try? JSONEncoder().encode(self) else { return nil }
return data
}
}
This works perfectly fine for encoding these kind of structures:
struct StoreRequest: RequestParameters {
var storeCode : String
var storeNumber : String
}
However, sometimes my requests require some "shared" parameters:
struct SpecialStoreRequest: RequestParameters {
var storeCode : String
var storeNumber : String
// Shared Parameters that appear in 70% of my requests
var sharedParam1 : String?
var sharedParam2 : String?
var sharedParam3 : String?
var sharedParam4 : String?
var sharedParam5 : String?
}
I could simply write these shared parameters on each of my request structures that need them, but I was wondering if it is possible to group them in another structure and somehow modify the encoding to encode them on the top level instead?
I'm thinking of something similar to this:
struct SharedParameters {
// Shared Parameters that appear in 70% of my requests
var sharedParam1: String?
var sharedParam2: String?
var sharedParam3: String?
var sharedParam4: String?
var sharedParam5: String?
enum CodingKeys: String, CodingKey {
case sharedParam1
case sharedParam2
case sharedParam3
case sharedParam4
case sharedParam5
}
}
struct SpecialStoreRequest: RequestParameters {
var storeCode : String
var storeNumber : String
var sharedParams : SharedParameters?
}
The problem with this last structure is that the resulting encoding is NOT the same as the first one because my shared parameters will be encoded INSIDE the "sharedParams" key:
{
"storeCode" : "ABC",
"storeNumber" : "123456",
"sharedParams" : {"sharedParam1" : "A","sharedParam2" : "B", ...}
}
But what I need is for them be encoded along my other existing parameters (storeCode & storeNumber in this case).
{
"storeCode" : "ABC",
"storeNumber" : "123456",
"sharedParam1" : "A",
"sharedParam2" : "B",
...
}
EDIT: To make the question clearer, assuming it is possible, what should go here to make this structure be encoded by key-value directly on its parent?
extension SharedParameters: Encodable {
func encode(to encoder: Encoder) throws {
// What goes here? (Is it even possible?)
}
}
You can't change the current
Encoder
and how it behaves but,You can achieve that by customizing the
Encode
functions,make two containers and use the shared parameters
CodingKeys
to encodeparameters inside your
sharedParameters
variable.Observe the code Below.
Usage Test
OUTPUT
Now lets take it to the next step,
Create a class and custom the
Encoder
of the shared there and just call its function.Observe the final result.
Now after Adding this class you can just use it like this, And it will give you the same result.