Reputation: 3725
I feel there's something I must be missing. Swift 5.1.
I have the following struct
which is set to be Decodable
so I can parse an external JSON URL:
struct ReleaseGroup: Decodable, Identifiable {
let id: Int
let externalServiceID: String
let title: String
let externalServiceImageURL: URL
let type: String
var image: UIImage?
private enum CodingKeys: String, CodingKey {
case id
case externalServiceID = "external_service_id"
case title
case externalServiceImageURL = "external_service_image_url"
case type
}
// do I have to do this just because UIImage is an optional?
init(id: Int, externalServiceID: String, title: String, externalServiceImageURL: URL, type: String) {
let url = URL(string: "https://someurl.com/some-image.jpeg")
let data = try? Data(contentsOf: url!)
self.image = UIImage(data: data!)
self.id = id
self.externalServiceID = externalServiceID
self.title = title
self.type = type
self.externalServiceImageURL = externalServiceImageURL
}
}
I've also defined this piece of code elsewhere, which is responsible for actually creating the instances from the API call:
init() {
guard let url = URL(string: "http://127.0.0.1:8000/api/releases/") else { return }
URLSession.shared.dataTask(with: url) { (data, _, _) in
guard let data = data else { return }
let releaseGroups = try! JSONDecoder().decode([ReleaseGroup].self, from: data)
DispatchQueue.main.async {
self.releaseGroups = releaseGroups
}
}
}.resume()
}
However, the above doesn't call the init()
method of ReleaseGroup
, which I thought is called any time an instance of ReleaseGroup
is created.
If I explicitly create them though, it works:
for releaseGroup in releaseGroups {
let rg = ReleaseGroup.init(id: releaseGroup.id, externalServiceID: releaseGroup.externalServiceID, title: releaseGroup.title, externalServiceImageURL: releaseGroup.externalServiceImageURL, type: releaseGroup.type)
self.releaseGroups.append(rg)
}
Upvotes: 1
Views: 708
Reputation: 51892
The decoder will call init(from:)
which is part of the Decodable
protocol. This init is synthesized so if you need to do something special with your object construction this is the init method you need to implement yourself.
See this article from Apple for more information
Upvotes: 2