I have a JSON response as shown below.
{
"data": [
{
"division": "Chemical",
"divisionid": 5
},
{
"division": "Corporate",
"divisionid": 12
},
{
"division": "Drilling",
"divisionid": 1
},
{
"division": "Energy",
"divisionid": 2
}
],
"response": {
"code": "413",
"message": "Success",
"status": "True",
"userToken": "XXXX"
}
}
My model classes are as follows
struct ApiResponse<T: Codable>: Codable {
let data: T
let response: Response
}
struct Division: Codable {
let divisionid: Int
let division: String
}
struct Response: Codable {
let code: String
let message: String
let status: String
let userToken: String
}
I am calling the Api as shown below
Calling Part
getDivisions () { result in
switch result {
case .success(let divisions):
print(divisions)
case .failure(let error):
print("Error: \(error.localizedDescription)")
}
}
Definition Part
func getDivisions(completed: @escaping (Result<[Division], ApiErrors>) -> Void) {
let endpoint = BaseUrl + ApiEndPoint.DivisionsList.description
guard let url = URL(string: endpoint) else {
completed(.failure(.invalidUsername))
return
}
guard (String(describing: UserDefaults.standard.string(forKey: "AuthCode"))) != "" else {
completed(.failure(.invalidAuthToken))
return
}
let localParameters: [String: Any] = [
"userToken": (UserDefaults.standard.string(forKey: "userTokenBI")) ?? "Default"
]
print("Auth Code retrieved: \(UserDefaults.standard.string(forKey: "authCodeUTS") ?? "Failed to get value")")
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type") // the request is JSON
request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Accept") // the expected response is also JSON
request.setValue("Basic \(String(describing: UserDefaults.standard.string(forKey: "authCodeUTS")))", forHTTPHeaderField: "Authorization")
request.timeoutInterval = 60.0
do {
request.httpBody = try JSONSerialization.data(withJSONObject: localParameters, options: .prettyPrinted)
} catch let error {
print(error.localizedDescription)
}
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if let _ = error {
completed(.failure(.unableToComplete))
//return
}
//HTTP here
guard let data = data else {
completed(.failure(.invalidData))
return
}
do {
let response = try JSONDecoder().decode(ApiResponse<[Division]>.self, from: data)
completed(.success(response.data))
} catch {
print(error)
completed(.failure(.invalidData))
}
}
task.resume()
}
But I am not able to return the data from the JSON response to the calling part since the parsing is not done properly. The error that I am getting is as follows
dataCorrupted(Swift.DecodingError.Context(codingPath: [], debugDescription: "The given data was not valid JSON.", underlyingError: Optional(Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0." UserInfo={NSDebugDescription=Invalid value around character 0.})))
Error: The operation couldn’t be completed.
Can someone help me to solve the issue that I am facing?
Thanks in advance
I would suggest creating your data types as below by removing unnecessary coding keys and initializers,
and update the
getDivisionmethod signature and decoding as below,As
ApiResponsedata will be generic so a better solution would be to declare it as belownow you can parse any data type expected from the API,
Usage:
Try below as a proof in
didFinishLaunchingWithOptionsof yourAppDelegate