I’m having a little issue with my Codable class…
I have an Int which I will Post on my API. But when I GET back, it is a String.
Let me show you some code:
this is my class:
Code Block Swift class NFCDataSec: ObservableObject, Codable { enum CodingKeys: String, CodingKey { case firstName, lastName, age } @Published var lastName: String = "" @Published var firstName: String = "" @Published var age: Int = 0 init() { } required init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) lastName = try container.decode(String.self, forKey: .lastName) firstName = try container.decode(String.self, forKey: .firstName) age = try container.decode(Int.self, forKey: .age) /* (1) */ } func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(firstName, forKey: .firstName) try container.encode(lastName, forKey: .lastName) try container.encode(age, forKey: .age) } }
this is my JSON Post request:
Code Block Swift func SecuringData() throws { guard let encoded = try? JSONEncoder().encode(dataToWrite) else { print("Fail to encode SecuringData - NFCDataSec") return } let url = URL(string: "https://MY_API.COM/api/sendToChip")! var request = URLRequest(url: url) request.setValue("application/json", forHTTPHeaderField: "Content-Type") request.httpMethod = "POST" request.httpBody = encoded URLSession.shared.dataTask(with: request) { data, res, error in guard let httpResponse = res as? HTTPURLResponse, (200...299).contains(httpResponse.statusCode) else { self.handleServerError(res) return } if let data = data { let decoder = JSONDecoder() if let json = try? decoder.decode(NFCDataSec.self, from: data) { print(json) } else { let dataString = String(decoding: data, as: UTF8.self) print("Invalid response \(dataString)") /* (2) */ } } }.resume()
(1) the API GET returns String instead of Int - but it needs to have Int when I’m making the POSTmethod
(2) I get an invalid response from the API when I GET the data back from it.
Here is an exemple of working JSON
POST:
Code Block { "lastName":"John", "firstName":"Taylor", "age":23 }
GET:
Code Block { "firstName": "8ac18f61", "lastName": "88cf8f64dc719eac6a", "age": "e893" }
If I understand correctly and to be sure, I need to to it in this part of the function, where I check the server's response ?If you expect dataToWrite to be updated, you need to explicitly update it in the completion handler of dataTask.
Code Block Swift if let data = data { let decoder = JSONDecoder() print("this is what i'm retreiving from the API \(String(decoding: data, as: UTF8.self))") if let json = try? decoder.decode(NFCDataSec.self, from: data) { print(json) print(self.dataToWrite.firstName) } }
And I need to do like so ?
Code Block Swift if let json = try? decoder.decode(NFCDataSec.self, from: data) { print(json) self.dataToWrite.firstName = json.firstName }