I'm using Alamofire5 and Swift 5.7.x.
There is a problem when I receive an response data from API server.
The response data default is:
{
statusCode: 200
message: "OK"
items: null
}
But the "items" attribute can be anything data type. null, string, int, array, object..
I was about to solve using Generics. But I don't know how to handle the null.
It's API common code:
struct Response<T: Codable>: Codable {
var statusCode: Int
var message: String
var items: T?
}
class API {
func request<Parameters: Encodable, T: Decodable>(_ path: String,
method: HTTPMethod = .get,
params: Parameters? = nil,
completion: @escaping (Result<Response<T?>, NetworkError>) -> Void) {
//some codes..
AF.request("\(path)",
method: method,
parameters: params,
encoder: JSONParameterEncoder.prettyPrinted
)
.validate(statusCode: 200..<400)
.validate(contentType: ["application/json"])
.responseData { response in
switch response.result {
case .success(let data):
guard let decodedData = try? JSONDecoder().decode(Response<T?>.self, from: data) else { return }
print(decodedData)
completion(.success(decodedData as Response<T?>))
case.failure(let error):
// some codes..
}
}
}
}
It's caller:
API.shared.request("/users/device", method: .post, params: reqParam) { (response: Result<Response<This is the problem..!!>, NetworkError>) in
switch response {
case .success(let data):
print("userDevice updated")
debugPrint(data)
case .failure(let error):
// some codes..
}
}
How can I pass nil on the caller?
Considering you have following response for all your API requests
{
statusCode: 200
message: "OK"
items: null
}
And your Codable struct as following
struct Response<T: Codable>: Codable {
var statusCode: Int
var message: String
var items: T? // Notice this is declared as Optional
}
As your items variable is declared as optional it will work as expected with little change.
You can declare an Empty Struct which can be used when you are expecting null
value for items
key, like following.
struct EmptyResponse: Codable {
}
You can use EmptyResponse
struct as following:
API.shared.request("/users/device", method: .post, params: reqParam) { (response: Result<Response<EmptyResponse>, NetworkError>) in
switch response {
case .success(let data):
debugPrint(data)
if let items = data.items {
// Use items here
} else {
// Items is nil
}
case .failure(let error):
// some codes..
}
}