diff --git a/Sources/OpenFoodFacts/OpenFoodFacts.swift b/Sources/OpenFoodFacts/OpenFoodFacts.swift index 57597a5..d9e31ad 100644 --- a/Sources/OpenFoodFacts/OpenFoodFacts.swift +++ b/Sources/OpenFoodFacts/OpenFoodFacts.swift @@ -29,6 +29,40 @@ public class OpenFoodFactsClient { return try JSONDecoder().decode(ProductResponse.self, from: data) } } + + public struct SearchQuery { + public let additivesTags: String? + public let allergensTags: String? + public let brandsTags: String? + public let categoriesTags: String? + public let countriesTagsEn: String? + public let embCodesTags: String? + public let labelsTags: String? + public let manufacturingPlacesTags: String? + public let nutritionGradesTags: String? + public let originsTags: String? + public let packagingTagsDe: String? + public let purchasePlacesTags: String? + } + + public func search(_ productName: String, queryParams: SearchQuery? = nil) async throws -> SearchResponse { + let qp = Mirror(reflecting: queryParams ?? {}) + var s: String = "?product_name=\(productName)&" + for case let (label?, value) in qp.children { + s += label.camelCaseToSnakeCase() + "=" + (value as! String) + "&" + } + guard let endpoint = baseURL?.appendingPathComponent("search\(s)") else { throw OFFError.invalidURL } + var request = URLRequest(url: endpoint) + request.setValue("application/json", forHTTPHeaderField: "accept") + + let (data, response) = try await URLSession.shared.data(for: request) + guard let response = response as? HTTPURLResponse, response.statusCode == 200 else { + throw OFFError.invalidResponse + } + do { + return try JSONDecoder().decode(SearchResponse.self, from: data) + } + } } enum OFFError: Error { diff --git a/Sources/exe/main.swift b/Sources/exe/main.swift index ed6d58e..f36b634 100644 --- a/Sources/exe/main.swift +++ b/Sources/exe/main.swift @@ -3,3 +3,11 @@ import OpenFoodFacts let off = OpenFoodFactsClient() off.prod = true + +do { + + let res = try await off.search("Coca-Cola") + print(res) +} catch { + print(error) +}