Dear All,
I try very hard to map Array/Dictionary data into a custom observed object and I need support.
The custom input object:
struct ImageAnnotation: Codable {
let labelAnnotations: [LabelAnnotations]
struct LabelAnnotations: Codable {
let description: String
let score: Double
}
}
The which maps (the constant ist just a test):
do {
let annotateImageResponse = try! JSONSerialization.data(withJSONObject: result!.data, options: .prettyPrinted)
let decoder = JSONDecoder()
let callResult = try! decoder.decode([ImageAnnotation].self, from: annotateImageResponse)
// print(callResult.description)
self.imageProperties = callResult.map { analyzeImage -> ImageProperties in
let description = callResult.description
let score = 9.2222
return ImageProperties(id: .init(), description: description, score: String(score))
}
}
}
}
The object which is getting mapped:
Printing description of callResult:
([ImageAnnotation]) callResult = 1 value {
[0] = {
labelAnnotations = 10 values {
[0] = (description = "Water", score = 0.97719752788543701)
[1] = (description = "Sky", score = 0.96194434165954589)
[2] = (description = "Plant", score = 0.91662931442260742)
[3] = (description = "Nature", score = 0.89995390176773071)
[4] = (description = "Natural landscape", score = 0.88719385862350464)
[5] = (description = "Highland", score = 0.86607605218887329)
[6] = (description = "Waterfall", score = 0.86192798614501953)
[7] = (description = "Body of water", score = 0.85812240839004517)
[8] = (description = "Vegetation", score = 0.84910452365875244)
[9] = (description = "Mountain", score = 0.8452027440071106)
}
}
}
The observable object:
import Foundation
struct ImageProperties: Identifiable {
let id: UUID
let description: String
let score: String
}
Could you help me out please?
Thanks a lot
tera
2
I don't quite understand the question.
example of ObservableObject:
class Model: ObservableObject {
@Published var state: MyState = ...
... more if needed
}
where
struct MyState {
var items: [Annotations] = ...
... more if needed
}
Your usage of json decoding looks strange... typically it is:
decoder.decode([ImageAnnotation].self, from: result.data)
i.e. without JSONSerialization step.
Dear tera,
Actually my question is how i can map this Array/Dictionary in callResult into the observable object below:
([ImageAnnotation]) callResult = 1 value {
[0] = {
labelAnnotations = 10 values {
[0] = (description = "Water", score = 0.97719752788543701)
[1] = (description = "Sky", score = 0.96194434165954589)
[2] = (description = "Plant", score = 0.91662931442260742)
[3] = (description = "Nature", score = 0.89995390176773071)
[4] = (description = "Natural landscape", score = 0.88719385862350464)
[5] = (description = "Highland", score = 0.86607605218887329)
[6] = (description = "Waterfall", score = 0.86192798614501953)
[7] = (description = "Body of water", score = 0.85812240839004517)
[8] = (description = "Vegetation", score = 0.84910452365875244)
[9] = (description = "Mountain", score = 0.8452027440071106)
import Foundation
struct ImageProperties: Identifiable {
let id: UUID
let description: String
let score: String
}
class ImageAnalyzer: ObservableObject {
@Published var imageProperties = ImageProperties
tera
4
In other words, you have an array of
struct LabelAnnotations: Codable {
let description: String
let score: Double
}
and you want it to map to array of
struct ImageProperties: Identifiable {
let id: UUID
let description: String
let score: String
}
Do you really need UUID? Maybe LabelAnnotations have unique description field? In which case you may use description as id:
struct LabelAnnotations: Codable, Identifiable {
var id: String { description }
let description: String
let score: Double
}
Or, if description is not unique, and neither is the combination of description + score, maybe array index can act as an identifier for you?
struct LabelAnnotations: Codable, Identifiable {
let id: Int // 0, 1, 2, ...
let description: String
let score: Double
}
Or maybe you don't need identifiable at all, just Hashable?
struct LabelAnnotations: Codable, Hashable {
let description: String
let score: Double
}
// needs identifiable items
// ForEach(items) { item in
// }
// ok with hashable items
ForEach(items, id: \.self) { item in
}
Or, perhaps there was some other identifier in your source material (where are you getting LabelAnnotations from?), and it's just a matter of propagating it? This is the best approach.