😑 using search-a-licious API now...
This commit is contained in:
@@ -9,7 +9,7 @@ extension KeyedDecodingContainer {
|
||||
return nil
|
||||
}
|
||||
|
||||
public func decodeStringOrInt(forKey key: Key) throws -> Int? {
|
||||
public func decodeIntOrString(forKey key: Key) throws -> Int? {
|
||||
if let intVal = try? decode(Int.self, forKey: key) {
|
||||
return intVal
|
||||
}
|
||||
@@ -19,4 +19,14 @@ extension KeyedDecodingContainer {
|
||||
return nil
|
||||
}
|
||||
|
||||
public func decodeStringOrArray(forKey key: Key) throws -> String? {
|
||||
if let arrayVal = try? decode([String].self, forKey: key) {
|
||||
return arrayVal.joined(separator: ",")
|
||||
}
|
||||
if let stringVal = try? decode(String.self, forKey: key) {
|
||||
return stringVal
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ public actor OpenFoodFactsClient {
|
||||
) async throws -> SearchResponseEnvelope {
|
||||
guard
|
||||
var components = URLComponents(
|
||||
url: config.apiURL.appendingPathComponent("/search"),
|
||||
url: config.searchURL,
|
||||
resolvingAgainstBaseURL: true)
|
||||
else {
|
||||
throw OFFError.invalidURL
|
||||
@@ -76,19 +76,19 @@ public actor OpenFoodFactsClient {
|
||||
for param in parameters {
|
||||
switch param {
|
||||
case .query(let q):
|
||||
queryItems.append(URLQueryItem(name: "search_terms", value: q))
|
||||
case .tag(let tag, let value):
|
||||
// V2 allows dynamic tags like `brands_tags=coca`
|
||||
queryItems.append(
|
||||
URLQueryItem(name: "\(tag.rawValue)_tags", value: value))
|
||||
queryItems.append(URLQueryItem(name: "q", value: q))
|
||||
// case .tag(let tag, let value):
|
||||
// // V2 allows dynamic tags like `brands_tags=coca`
|
||||
// queryItems.append(
|
||||
// URLQueryItem(name: "\(tag.rawValue)_tags", value: value))
|
||||
case .page(let p):
|
||||
queryItems.append(URLQueryItem(name: "page", value: String(p)))
|
||||
case .pageSize(let s):
|
||||
queryItems.append(
|
||||
URLQueryItem(name: "page_size", value: String(s)))
|
||||
case .sort(let s):
|
||||
queryItems.append(
|
||||
URLQueryItem(name: "sort_by", value: s.rawValue))
|
||||
// case .sort(let s):
|
||||
// queryItems.append(
|
||||
// URLQueryItem(name: "sort_by", value: s.rawValue))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,11 +140,11 @@ public struct SearchResponseEnvelope: Sendable, Decodable {
|
||||
public let count: Int
|
||||
public let page: Int
|
||||
public let pageSize: Int
|
||||
public let products: [Product]
|
||||
public let hits: [Product]
|
||||
public let pageCount: Int
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case count, page, products
|
||||
case count, page, hits
|
||||
case pageSize = "page_size"
|
||||
case pageCount = "page_count"
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ public struct OpenFoodFactsConfig: Sendable {
|
||||
public let baseURL: URL
|
||||
public let userAgent: UserAgent
|
||||
public let apiURL: URL
|
||||
public let searchURL: URL
|
||||
|
||||
public struct UserAgent: CustomStringConvertible, Sendable {
|
||||
public let appName: String
|
||||
@@ -62,5 +63,6 @@ public struct OpenFoodFactsConfig: Sendable {
|
||||
self.baseURL = environment.url
|
||||
self.userAgent = userAgent
|
||||
self.apiURL = self.baseURL.appendingPathComponent("/api/v2")
|
||||
self.searchURL = URL(string: "https://search.openfoodfacts.org/search")!
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,10 +35,10 @@ public struct NutriscoreData: Sendable, Codable {
|
||||
|
||||
isBeverage = try container.decodeIfPresent(
|
||||
Int.self, forKey: .isBeverage)
|
||||
isCheese = try container.decodeStringOrInt(forKey: .isCheese)
|
||||
isWater = try container.decodeStringOrInt(forKey: .isWater)
|
||||
isFat = try container.decodeStringOrInt(forKey: .isFat)
|
||||
energy = try container.decodeStringOrInt(forKey: .energy)
|
||||
isCheese = try container.decodeIntOrString(forKey: .isCheese)
|
||||
isWater = try container.decodeIntOrString(forKey: .isWater)
|
||||
isFat = try container.decodeIntOrString(forKey: .isFat)
|
||||
energy = try container.decodeIntOrString(forKey: .energy)
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -147,7 +147,7 @@ public struct Product: Codable, Sendable, Identifiable {
|
||||
String.self, forKey: .productName)
|
||||
genericName = try container.decodeIfPresent(
|
||||
String.self, forKey: .genericName)
|
||||
brands = try container.decodeIfPresent(String.self, forKey: .brands)
|
||||
brands = try container.decodeStringOrArray(forKey: .brands)
|
||||
brandsTags = try container.decodeIfPresent(
|
||||
[String].self, forKey: .brandsTags)
|
||||
quantity = try container.decodeIfPresent(String.self, forKey: .quantity)
|
||||
|
||||
@@ -2,10 +2,10 @@ import Foundation
|
||||
|
||||
public enum SearchParameter: Sendable, Hashable {
|
||||
case query(String)
|
||||
case tag(tag: SearchTagType, value: String)
|
||||
// case tag(tag: SearchTagType, value: String)
|
||||
case page(Int)
|
||||
case pageSize(Int)
|
||||
case sort(SearchSort)
|
||||
// case sort(SearchSort)
|
||||
}
|
||||
|
||||
public enum SearchTagType: String, Sendable {
|
||||
|
||||
Reference in New Issue
Block a user