From d1cb8732b473fe2f5c462fbd9493964f243744d7 Mon Sep 17 00:00:00 2001 From: cdricms <36056008+cdricms@users.noreply.github.com> Date: Mon, 15 Jan 2024 19:53:22 +0100 Subject: [PATCH] Fixed some forgotten properties to decode + type conversion --- Sources/OpenFoodFacts/types/Nutriments.swift | 16 +- Sources/OpenFoodFacts/types/Product.swift | 259 ++++++++++++++++++- 2 files changed, 264 insertions(+), 11 deletions(-) diff --git a/Sources/OpenFoodFacts/types/Nutriments.swift b/Sources/OpenFoodFacts/types/Nutriments.swift index 8221273..0afac78 100644 --- a/Sources/OpenFoodFacts/types/Nutriments.swift +++ b/Sources/OpenFoodFacts/types/Nutriments.swift @@ -21,18 +21,18 @@ public struct Nutriments: Codable, ObjectDebugger { public var cholesterolServing: Float? = 0.0 public var cholesterolUnit: String? = nil - public var energy: Int? = 0 - public var energyKcal: Int? = 0 - public var energyKj: Int? = 0 - public var energyValue: Int? = 0 - public var energyKcalValue: Int? = 0 - public var energyKjValue: Int? = 0 + public var energy: Float? = 0 + public var energyKcal: Float? = 0 + public var energyKj: Float? = 0 + public var energyValue: Float? = 0 + public var energyKcalValue: Float? = 0 + public var energyKjValue: Float? = 0 public var energy100G: Float? = 0 - public var energyKcal100G: Int? = 0 + public var energyKcal100G: Float? = 0 public var energyKj100G: Float? = 0 public var energyServing: Int? = 0 public var energyKcalServing: Double? = 0.0 - public var energyKjServing: Int? = 0 + public var energyKjServing: Float? = 0 public var energyUnit: String? = nil public var energyKcalUnit: String? = nil public var energyKjUnit: String? = nil diff --git a/Sources/OpenFoodFacts/types/Product.swift b/Sources/OpenFoodFacts/types/Product.swift index 19a65fb..1bbe2ca 100644 --- a/Sources/OpenFoodFacts/types/Product.swift +++ b/Sources/OpenFoodFacts/types/Product.swift @@ -67,7 +67,6 @@ public class Product: Codable, ObjectDebugger { public var fruitsVegetablesNuts100GEstimate: Int? public var genericName: String? public var id: String? - public var _id: String? public var imageFrontSmallUrl: String? public var imageFrontThumbUrl: String? public var imageFrontUrl: String? @@ -400,6 +399,260 @@ public class Product: Codable, ObjectDebugger { public required init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) + ingredients = try container.decodeIfPresent([Ingredient].self, forKey: .ingredients) + languagesCodes = try container.decodeIfPresent(LanguagesCodes.self, forKey: .languagesCodes) + nutrientLevels = try container.decodeIfPresent(NutrientLevels.self, forKey: .nutrientLevels) + nutriments = try container.decodeIfPresent(Nutriments.self, forKey: .nutriments) ?? Nutriments() + selectedImages = try container.decodeIfPresent(SelectedImages.self, forKey: .selectedImages) + sources = try container.decodeIfPresent([Source].self, forKey: .sources) + additivesN = try container.decodeIfPresent(Int.self, forKey: .additivesN) + additivesOldN = try container.decodeIfPresent(Int.self, forKey: .additivesOldN) + additivesOriginalTags = try container.decodeIfPresent([String].self, forKey: .additivesOriginalTags) + additivesOldTags = try container.decodeIfPresent([String].self, forKey: .additivesOldTags) + additivesPrevOriginalTags = try container.decodeIfPresent([String].self, forKey: .additivesPrevOriginalTags) + additivesDebugTags = try container.decodeIfPresent([String].self, forKey: .additivesDebugTags) + additivesTags = try container.decodeIfPresent([String].self, forKey: .additivesTags) + allergens = try container.decodeIfPresent(String.self, forKey: .allergens) + allergensFromIngredients = try container.decodeIfPresent(String.self, forKey: .allergensFromIngredients) + allergensFromUser = try container.decodeIfPresent(String.self, forKey: .allergensFromUser) + allergensHierarchy = try container.decodeIfPresent([String].self, forKey: .allergensHierarchy) + allergensLc = try container.decodeIfPresent(String.self, forKey: .allergensLc) + allergensTags = try container.decodeIfPresent([String].self, forKey: .allergensTags) + aminoAcidsPrevTags = try container.decodeIfPresent([String].self, forKey: .aminoAcidsPrevTags) + aminoAcidsTags = try container.decodeIfPresent([String].self, forKey: .aminoAcidsTags) + brands = try container.decodeIfPresent(String.self, forKey: .brands) + brandsDebugTags = try container.decodeIfPresent([String].self, forKey: .brandsDebugTags) + brandsTags = try container.decodeIfPresent([String].self, forKey: .brandsTags) + carbonFootprintPercentOfKnownIngredients = try container.decodeIfPresent(Float.self, forKey: .carbonFootprintPercentOfKnownIngredients) + carbonFootprintFromKnownIngredientsDebug = try container.decodeIfPresent(String.self, forKey: .carbonFootprintFromKnownIngredientsDebug) + categories = try container.decodeIfPresent(String.self, forKey: .categories) + categoriesHierarchy = try container.decodeIfPresent([String].self, forKey: .categoriesHierarchy) + categoriesLc = try container.decodeIfPresent(String.self, forKey: .categoriesLc) + categoriesPropertiesTags = try container.decodeIfPresent([String].self, forKey: .categoriesPropertiesTags) + categoriesTags = try container.decodeIfPresent([String].self, forKey: .categoriesTags) + checkersTags = try container.decodeIfPresent([String].self, forKey: .checkersTags) + citiesTags = try container.decodeIfPresent([String].self, forKey: .citiesTags) + code = try container.decodeIfPresent(String.self, forKey: .code) + codesTags = try container.decodeIfPresent([String].self, forKey: .codesTags) + comparedToCategory = try container.decodeIfPresent(String.self, forKey: .comparedToCategory) + complete = try container.decodeIfPresent(Int.self, forKey: .complete) + completedT = try container.decodeIfPresent(Int.self, forKey: .completedT) + completeness = try container.decodeIfPresent(Double.self, forKey: .completeness) + conservationConditions = try container.decodeIfPresent(String.self, forKey: .conservationConditions) + countries = try container.decodeIfPresent(String.self, forKey: .countries) + countriesHierarchy = try container.decodeIfPresent([String].self, forKey: .countriesHierarchy) + countriesLc = try container.decodeIfPresent(String.self, forKey: .countriesLc) + countriesDebugTags = try container.decodeIfPresent([String].self, forKey: .countriesDebugTags) + countriesTags = try container.decodeIfPresent([String].self, forKey: .countriesTags) + correctorsTags = try container.decodeIfPresent([String].self, forKey: .correctorsTags) + createdT = try container.decodeIfPresent(Int.self, forKey: .createdT) + creator = try container.decodeIfPresent(String.self, forKey: .creator) + dataQualityBugsTags = try container.decodeIfPresent([String].self, forKey: .dataQualityBugsTags) + dataQualityErrorsTags = try container.decodeIfPresent([String].self, forKey: .dataQualityErrorsTags) + dataQualityInfoTags = try container.decodeIfPresent([String].self, forKey: .dataQualityInfoTags) + dataQualityTags = try container.decodeIfPresent([String].self, forKey: .dataQualityTags) + dataQualityWarningsTags = try container.decodeIfPresent([String].self, forKey: .dataQualityWarningsTags) + dataSources = try container.decodeIfPresent(String.self, forKey: .dataSources) + dataSourcesTags = try container.decodeIfPresent([String].self, forKey: .dataSourcesTags) + debugParamSortedLangs = try container.decodeIfPresent([String].self, forKey: .debugParamSortedLangs) + editorsTags = try container.decodeIfPresent([String].self, forKey: .editorsTags) + embCodes = try container.decodeIfPresent(String.self, forKey: .embCodes) + embCodesDebugTags = try container.decodeIfPresent([String].self, forKey: .embCodesDebugTags) + embCodesOrig = try container.decodeIfPresent(String.self, forKey: .embCodesOrig) + embCodesTags = try container.decodeIfPresent([String].self, forKey: .embCodesTags) + entryDatesTags = try container.decodeIfPresent([String].self, forKey: .entryDatesTags) + expirationDate = try container.decodeIfPresent(String.self, forKey: .expirationDate) + expirationDateDebugTags = try container.decodeIfPresent([String].self, forKey: .expirationDateDebugTags) + fruitsVegetablesNuts100GEstimate = try container.decodeIfPresent(Int.self, forKey: .fruitsVegetablesNuts100GEstimate) + genericName = try container.decodeIfPresent(String.self, forKey: .genericName) + id = try container.decodeIfPresent(String.self, forKey: .id) + imageFrontSmallUrl = try container.decodeIfPresent(String.self, forKey: .imageFrontSmallUrl) + imageFrontThumbUrl = try container.decodeIfPresent(String.self, forKey: .imageFrontThumbUrl) + imageFrontUrl = try container.decodeIfPresent(String.self, forKey: .imageFrontUrl) + imageIngredientsUrl = try container.decodeIfPresent(String.self, forKey: .imageIngredientsUrl) + imageIngredientsSmallUrl = try container.decodeIfPresent(String.self, forKey: .imageIngredientsSmallUrl) + imageIngredientsThumbUrl = try container.decodeIfPresent(String.self, forKey: .imageIngredientsThumbUrl) + imageNutritionSmallUrl = try container.decodeIfPresent(String.self, forKey: .imageNutritionSmallUrl) + imageNutritionThumbUrl = try container.decodeIfPresent(String.self, forKey: .imageNutritionThumbUrl) + imageNutritionUrl = try container.decodeIfPresent(String.self, forKey: .imageNutritionUrl) + imageSmallUrl = try container.decodeIfPresent(String.self, forKey: .imageSmallUrl) + imageThumbUrl = try container.decodeIfPresent(String.self, forKey: .imageThumbUrl) + imageUrl = try container.decodeIfPresent(String.self, forKey: .imageUrl) + informersTags = try container.decodeIfPresent([String].self, forKey: .informersTags) + ingredientsAnalysisTags = try container.decodeIfPresent([String].self, forKey: .ingredientsAnalysisTags) + ingredientsDebug = try container.decodeIfPresent([String?].self, forKey: .ingredientsDebug) + ingredientsFromOrThatMayBeFromPalmOilN = try container.decodeIfPresent(Int.self, forKey: .ingredientsFromOrThatMayBeFromPalmOilN) + ingredientsFromPalmOilTags = try container.decodeIfPresent([String].self, forKey: .ingredientsFromPalmOilTags) + ingredientsFromPalmOilN = try container.decodeIfPresent(Int.self, forKey: .ingredientsFromPalmOilN) + ingredientsHierarchy = try container.decodeIfPresent([String].self, forKey: .ingredientsHierarchy) + ingredientsIdsDebug = try container.decodeIfPresent([String].self, forKey: .ingredientsIdsDebug) + if container.contains(.ingredientsN) { + if try container.decodeNil(forKey: .ingredientsN) { + ingredientsN = nil + } else { + if let intValue = try? container.decode(Int.self, forKey: .ingredientsN) { + ingredientsN = intValue + } else if let stringValue = try? container.decode(String.self, forKey: .ingredientsN) { + ingredientsN = Int(stringValue) + }else { + // If decoding as both Int and String fails, handle the error accordingly + throw DecodingError.dataCorruptedError( + forKey: .ingredientsN, + in: container, + debugDescription: "Unable to decode ingredientsN" + ) + } + + } + } else { + ingredientsN = nil + } + ingredientsNTags = try container.decodeIfPresent([String].self, forKey: .ingredientsNTags) + ingredientsOriginalTags = try container.decodeIfPresent([String].self, forKey: .ingredientsOriginalTags) + ingredientsTags = try container.decodeIfPresent([String].self, forKey: .ingredientsTags) + ingredientsText = try container.decodeIfPresent(String.self, forKey: .ingredientsText) + ingredientsTextDebug = try container.decodeIfPresent(String.self, forKey: .ingredientsTextDebug) + ingredientsTextWithAllergens = try container.decodeIfPresent(String.self, forKey: .ingredientsTextWithAllergens) + ingredientsThatMayBeFromPalmOilN = try container.decodeIfPresent(Int.self, forKey: .ingredientsThatMayBeFromPalmOilN) + ingredientsThatMayBeFromPalmOilTags = try container.decodeIfPresent([String].self, forKey: .ingredientsThatMayBeFromPalmOilTags) + interfaceVersionCreated = try container.decodeIfPresent(String.self, forKey: .interfaceVersionCreated) + interfaceVersionModified = try container.decodeIfPresent(String.self, forKey: .interfaceVersionModified) + keywords = try container.decodeIfPresent([String].self, forKey: .keywords) + knownIngredientsN = try container.decodeIfPresent(Int.self, forKey: .knownIngredientsN) + labels = try container.decodeIfPresent(String.self, forKey: .labels) + labelsHierarchy = try container.decodeIfPresent([String].self, forKey: .labelsHierarchy) + labelsLc = try container.decodeIfPresent(String.self, forKey: .labelsLc) + labelsPrevHierarchy = try container.decodeIfPresent([String].self, forKey: .labelsPrevHierarchy) + labelsPrevTags = try container.decodeIfPresent([String].self, forKey: .labelsPrevTags) + labelsTags = try container.decodeIfPresent([String].self, forKey: .labelsTags) + labelsDebugTags = try container.decodeIfPresent([String].self, forKey: .labelsDebugTags) + lang = try container.decodeIfPresent(String.self, forKey: .lang) + langDebugTags = try container.decodeIfPresent([String].self, forKey: .langDebugTags) + languagesHierarchy = try container.decodeIfPresent([String].self, forKey: .languagesHierarchy) + languagesTags = try container.decodeIfPresent([String].self, forKey: .languagesTags) + lastEditDatesTags = try container.decodeIfPresent([String].self, forKey: .lastEditDatesTags) + lastEditor = try container.decodeIfPresent(String.self, forKey: .lastEditor) + lastImageDatesTags = try container.decodeIfPresent([String].self, forKey: .lastImageDatesTags) + lastImageT = try container.decodeIfPresent(Int.self, forKey: .lastImageT) + lastModifiedBy = try container.decodeIfPresent(String.self, forKey: .lastModifiedBy) + lastModifiedT = try container.decodeIfPresent(Int.self, forKey: .lastModifiedT) + lc = try container.decodeIfPresent(String.self, forKey: .lc) + link = try container.decodeIfPresent(String.self, forKey: .link) + linkDebugTags = try container.decodeIfPresent([String].self, forKey: .linkDebugTags) + manufacturingPlaces = try container.decodeIfPresent(String.self, forKey: .manufacturingPlaces) + manufacturingPlacesDebugTags = try container.decodeIfPresent([String].self, forKey: .manufacturingPlacesDebugTags) + manufacturingPlacesTags = try container.decodeIfPresent([String].self, forKey: .manufacturingPlacesTags) + maxImgid = try container.decodeIfPresent(String.self, forKey: .maxImgid) + mineralsPrevTags = try container.decodeIfPresent([String].self, forKey: .mineralsPrevTags) + mineralsTags = try container.decodeIfPresent([String].self, forKey: .mineralsTags) + miscTags = try container.decodeIfPresent([String].self, forKey: .miscTags) + netWeightUnit = try container.decodeIfPresent(String.self, forKey: .netWeightUnit) + netWeightValue = try container.decodeIfPresent(String.self, forKey: .netWeightValue) + nutritionDataPer = try container.decodeIfPresent(String.self, forKey: .nutritionDataPer) + nutritionScoreWarningNoFruitsVegetablesNuts = try container.decodeIfPresent(Int.self, forKey: .nutritionScoreWarningNoFruitsVegetablesNuts) + noNutritionData = try container.decodeIfPresent(String.self, forKey: .noNutritionData) + novaGroup = try container.decodeIfPresent(Int.self, forKey: .novaGroup) + novaGroups = try container.decodeIfPresent(String.self, forKey: .novaGroups) + novaGroupDebug = try container.decodeIfPresent(String.self, forKey: .novaGroupDebug) + novaGroupTags = try container.decodeIfPresent([String].self, forKey: .novaGroupTags) + novaGroupsTags = try container.decodeIfPresent([String].self, forKey: .novaGroupsTags) + nucleotidesTags = try container.decodeIfPresent([String].self, forKey: .nucleotidesTags) + nutrientLevelsTags = try container.decodeIfPresent([String].self, forKey: .nutrientLevelsTags) + nutritionData = try container.decodeIfPresent(String.self, forKey: .nutritionData) + nutritionDataPerDebugTags = try container.decodeIfPresent([String].self, forKey: .nutritionDataPerDebugTags) + nutritionDataPrepared = try container.decodeIfPresent(String.self, forKey: .nutritionDataPrepared) + nutritionDataPreparedPer = try container.decodeIfPresent(String.self, forKey: .nutritionDataPreparedPer) + nutritionGrades = try container.decodeIfPresent(String.self, forKey: .nutritionGrades) + nutritionScoreBeverage = try container.decodeIfPresent(Int.self, forKey: .nutritionScoreBeverage) + nutritionScoreDebug = try container.decodeIfPresent(String.self, forKey: .nutritionScoreDebug) + nutritionScoreWarningNoFiber = try container.decodeIfPresent(Int.self, forKey: .nutritionScoreWarningNoFiber) + nutritionGradesTags = try container.decodeIfPresent([String].self, forKey: .nutritionGradesTags) + origins = try container.decodeIfPresent(String.self, forKey: .origins) + originsDebugTags = try container.decodeIfPresent([String].self, forKey: .originsDebugTags) + originsTags = try container.decodeIfPresent([String].self, forKey: .originsTags) + otherInformation = try container.decodeIfPresent(String.self, forKey: .otherInformation) + otherNutritionalSubstancesTags = try container.decodeIfPresent([String].self, forKey: .otherNutritionalSubstancesTags) + packaging = try container.decodeIfPresent(String.self, forKey: .packaging) + packagingDebugTags = try container.decodeIfPresent([String].self, forKey: .packagingDebugTags) + packagingTags = try container.decodeIfPresent([String].self, forKey: .packagingTags) + photographersTags = try container.decodeIfPresent([String].self, forKey: .photographersTags) + pnnsGroups1 = try container.decodeIfPresent(String.self, forKey: .pnnsGroups1) + pnnsGroups2 = try container.decodeIfPresent(String.self, forKey: .pnnsGroups2) + pnnsGroups1Tags = try container.decodeIfPresent([String].self, forKey: .pnnsGroups1Tags) + pnnsGroups2Tags = try container.decodeIfPresent([String].self, forKey: .pnnsGroups2Tags) + popularityKey = try container.decodeIfPresent(Int.self, forKey: .popularityKey) + producerVersionId = try container.decodeIfPresent(String.self, forKey: .producerVersionId) + productName = try container.decodeIfPresent(String.self, forKey: .productName) + purchasePlaces = try container.decodeIfPresent(String.self, forKey: .purchasePlaces) + purchasePlacesDebugTags = try container.decodeIfPresent([String].self, forKey: .purchasePlacesDebugTags) + purchasePlacesTags = try container.decodeIfPresent([String].self, forKey: .purchasePlacesTags) + qualityTags = try container.decodeIfPresent([String].self, forKey: .qualityTags) + quantity = try container.decodeIfPresent(String.self, forKey: .quantity) + quantityDebugTags = try container.decodeIfPresent([String].self, forKey: .quantityDebugTags) + recyclingInstructionsToDiscard = try container.decodeIfPresent(String.self, forKey: .recyclingInstructionsToDiscard) + rev = try container.decodeIfPresent(Int.self, forKey: .rev) + if container.contains(.servingQuantity) { + if try container.decodeNil(forKey: .servingQuantity) { + servingQuantity = nil + } else { + if let floatValue = try? container.decode(Float.self, forKey: .servingQuantity) { + servingQuantity = "\(floatValue)" + } else if let stringValue = try? container.decode(String.self, forKey: .servingQuantity) { + servingQuantity = stringValue + }else { + // If decoding as both Int and String fails, handle the error accordingly + throw DecodingError.dataCorruptedError( + forKey: .servingQuantity, + in: container, + debugDescription: "Unable to decode servingQuantity" + ) + } + + } + } else { + servingQuantity = nil + } + servingSize = try container.decodeIfPresent(String.self, forKey: .servingSize) + servingSizeDebugTags = try container.decodeIfPresent([String].self, forKey: .servingSizeDebugTags) + sortkey = try container.decodeIfPresent(Int.self, forKey: .sortkey) + states = try container.decodeIfPresent(String.self, forKey: .states) + statesHierarchy = try container.decodeIfPresent([String].self, forKey: .statesHierarchy) + statesTags = try container.decodeIfPresent([String].self, forKey: .statesTags) + stores = try container.decodeIfPresent(String.self, forKey: .stores) + storesDebugTags = try container.decodeIfPresent([String].self, forKey: .storesDebugTags) + storesTags = try container.decodeIfPresent([String].self, forKey: .storesTags) + traces = try container.decodeIfPresent(String.self, forKey: .traces) + tracesFromIngredients = try container.decodeIfPresent(String.self, forKey: .tracesFromIngredients) + tracesHierarchy = try container.decodeIfPresent([String].self, forKey: .tracesHierarchy) + tracesDebugTags = try container.decodeIfPresent([String].self, forKey: .tracesDebugTags) + tracesFromUser = try container.decodeIfPresent(String.self, forKey: .tracesFromUser) + tracesLc = try container.decodeIfPresent(String.self, forKey: .tracesLc) + tracesTags = try container.decodeIfPresent([String].self, forKey: .tracesTags) + if container.contains(.unknownIngredientsN) { + if try container.decodeNil(forKey: .unknownIngredientsN) { + unknownIngredientsN = nil + } else { + if let intValue = try? container.decode(Int.self, forKey: .unknownIngredientsN) { + unknownIngredientsN = intValue + } else if let stringValue = try? container.decode(String.self, forKey: .unknownIngredientsN) { + unknownIngredientsN = Int(stringValue) + }else { + // If decoding as both Int and String fails, handle the error accordingly + throw DecodingError.dataCorruptedError( + forKey: .unknownIngredientsN, + in: container, + debugDescription: "Unable to decode unknownIngredientsN" + ) + } + + } + } else { + unknownIngredientsN = nil + } + unknownNutrientsTags = try container.decodeIfPresent([String].self, forKey: .unknownNutrientsTags) + updateKey = try container.decodeIfPresent(String.self, forKey: .updateKey) + vitaminsPrevTags = try container.decodeIfPresent([String].self, forKey: .vitaminsPrevTags) + vitaminsTags = try container.decodeIfPresent([String].self, forKey: .vitaminsTags) // Check for null value if container.contains(.productQuantity) { @@ -407,8 +660,8 @@ public class Product: Codable, ObjectDebugger { productQuantity = nil } else { // Try to decode as Int - if let intValue = try? container.decode(Float.self, forKey: .productQuantity) { - productQuantity = intValue + if let floatValue = try? container.decode(Float.self, forKey: .productQuantity) { + productQuantity = floatValue } else if let stringValue = try? container.decode(String.self, forKey: .productQuantity) { // If decoding as Int fails, try to decode as String productQuantity = Float(stringValue)