Reputation: 736
I want to convert a CollegeRequest type to a dictionary or data to send it to a server while requesting POST-API.
Here is my CollegeRequest type:
struct CollegeRequest: Codable {
struct Student: Codable {
var id: Int
var name: String
}
var student: Student
var date: Date
}
Once converted (along with the hierarchical keys), it should be like this:
{
"student.id": 3,
"student.name": "Raj",
"date": "2019-10-31T13:59:00+00:00"
}
How can I achieve this ?
Upvotes: 0
Views: 201
Reputation: 9925
Use Encodable protocol to encode your cutom struct type CollegeRequest. Your structure needs a manual encoding
If the structure of your Swift type differs from the structure of its encoded form, you can provide a custom implementation of Encodable and Decodable to define your own encoding and decoding logic. source
To encode the CollegeRequest to Data type, use JSONEncoder. An object that encodes instances of a data type as JSON objects.
Concerning the date stored property you you have to use JSONEncoder.DateEncodingStrategy.formatted(_:), the strategy that defers formatting settings to a supplied date formatter.
struct CollegeRequest: Codable {
struct Student: Codable {
var id: Int
var name: String
}
var student: Student
var date: Date
enum CodingKeys: String, CodingKey {
case studentId = "student.id"
case studentName = "student.name"
case date
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(student.id, forKey: .studentId)
try container.encode(student.name, forKey: .studentName)
try container.encode(date, forKey: .date)
}
init(student: CollegeRequest.Student, date: Date) {
self.student = student
self.date = date
}
init(from decoder: Decoder) throws {
let values = try decoder.container(keyedBy: CodingKeys.self)
let studentId = try values.decode(Int.self, forKey: .studentId)
let studentName = try values.decode(String.self, forKey: .studentName)
student = Student(id: studentId, name: studentName)
date = try values.decode(Date.self, forKey: .date)
}
}
Usage
let request = CollegeRequest(student: CollegeRequest.Student(id: 1, name: "John"), date: Date())
let jsonEncoder = JSONEncoder()
let df = { let df = DateFormatter(); df.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"; return df }() as DateFormatter
jsonEncoder.dateEncodingStrategy = .formatted(df)
let a: Data? = try? jsonEncoder.encode(request)
Upvotes: 1