This is the struct having id and image url :
struct SampleImageLink:Codable{
let success:Bool
let message:String
let linkResponse:[LinkResponse]
enum CodingKeys: String, CodingKey{
case success = "IsSuccess"
case message = "Message"
case linkResponse = "ResponseData"
}
}
struct LinkResponse:Codable,Identifiable{
var id:Int
let fileName:String
//fileName is the link for image url and id is unique id associated with url
enum CodingKeys: String, CodingKey{
case id = "Id"
case fileName = "FileName"
}
}
Given below is the json response from another API
{
"IsSuccess": true,
"Message": "Data Returned",
"ResponseData": [
{
"TestId": 681,
"TestName": "Acidity Check Profile",
"Type": "Package",
"MRP": 0.0,
"NetAmount": 0.0,
"TestListForPackage": [
{
"TestId": 274,
"TestName": "Sugar (Glucose) Fasting",
"TestCode": null,
"Type": null,
"MRP": 0.0,
"NetAmount": 0.0,
"TestPackageGroupId": null,
"MetabolitesList": [
{
"MetaboliteId": 820,
"MetaboliteName": "Glucose (Fasting)",
"TestName": null
}
],
"TurnAroundTime": 4,
"TurnAroundTimeString": ""
},
{
"TestId": 1096,
"TestName": "Serum Electrolyte Profile",
"TestCode": null,
"Type": null,
"MRP": 0.0,
"NetAmount": 0.0,
"TestPackageGroupId": null,
"MetabolitesList": [
{
"MetaboliteId": 1117,
"MetaboliteName": "Chloride",
"TestName": null
},
{
"MetaboliteId": 1116,
"MetaboliteName": "Potassium",
"TestName": null
},
{
"MetaboliteId": 1115,
"MetaboliteName": "Sodium",
"TestName": null
}
],
"TurnAroundTime": 4,
"TurnAroundTimeString": ""
},
],
"SampleTypeList": [
{
"TestSampleTypeId": "51",
"SampleName": "Fluoride Plasma - F",
"PackageId": 681,
"PackageName": null
},
{
"TestSampleTypeId": "55",
"SampleName": "EDTA Whole Blood",
"PackageId": 681,
"PackageName": null
},
{
"TestSampleTypeId": "50",
"SampleName": "Serum",
"PackageId": 681,
"PackageName": null
}
]
}
]
}
Below is the struct for above json.
struct PriceDetailResponse:Codable{
let success:Bool
let message:String
let response:[DetailResponse]
enum CodingKeys: String, CodingKey{
case success = "IsSuccess"
case message = "Message"
case response = "ResponseData"
}}
struct DetailResponse:Codable, Identifiable{
var id: Int{testId}
let testId:Int
//define items
let testPackage:[TestListPackage]
let sampleType:[SampleList]
enum CodingKeys: String, CodingKey{
case testId = "TestId"
//define items
case testPackage = "TestListForPackage"
case sampleType = "SampleTypeList"
}
}
struct TestListPackage:Codable{
//define all items
let metabolite : [Metabolites]
enum CodingKeys: String, CodingKey{
case metabolite = "MetabolitesList"
}
}
struct Metabolites:Codable{
//define items
}
struct SampleList:Codable, Identifiable{
var id:Int{packageId}
let testSampleTypeId : String
let sampleName : String
let packageId : Int
let packageName : String?
enum CodingKeys: String, CodingKey{
case testSampleTypeId = "TestSampleTypeId"
case sampleName = "SampleName"
case packageId = "PackageId"
case packageName = "PackageName"
}
}
All is working fine. I have also displayed images using UIImage and Asyncimage. However, the requirement is image should be displayed if
Id from SampleImageLink struct == TestSampleTypeId of SampleList struct
I have created a view to display images, now need to filter the ids so that only the above matching id images should display
for eg:
ForEach(imgModel.link.filter{$0.id == 51}){img in
ImageLoader(urlString: img.fileName)
}
//imgModel is the ImageViewModel object.
is working fine. But how to iterate over SampleList and match with id of image What is the way to do it (id in SampleImageLink is int whereas in SampleList, testSampleTypeId is string).
CodePudding user response:
One approach could be to cast testSampleTypeId
to an Int
while decoding. This way you can compare to it in the ForEach
loop:
struct SampleList:Codable, Identifiable{
var id:Int{packageId}
let testSampleTypeId : Int
let sampleName : String
let packageId : Int
let packageName : String?
enum CodingKeys: String, CodingKey{
case testSampleTypeId = "TestSampleTypeId"
case sampleName = "SampleName"
case packageId = "PackageId"
case packageName = "PackageName"
}
init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
sampleName = try container.decode(String.self, forKey: .sampleName)
packageId = try container.decode(Int.self, forKey: .packageId)
packageName = try container.decodeIfPresent(String.self, forKey: .packageName)
// decode to a String, cast it to an Int and check if successfull; else throw error
guard let testSampleTypeId = Int(try container.decode(String.self, forKey: .testSampleTypeId)) else{
throw DecodingError.dataCorrupted(.init(codingPath: [CodingKeys.testSampleTypeId], debugDescription: "TestSampleTypeId could not be casted to type Int"))
}
self.testSampleTypeId = testSampleTypeId
}
}