Skip to content

Commit 4697311

Browse files
committed
Public interfaces, small fixes
1 parent af0722d commit 4697311

File tree

8 files changed

+104
-20
lines changed

8 files changed

+104
-20
lines changed

Sources/Extensions/Extensions.swift

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,3 +163,63 @@ public extension [String: String] {
163163
}
164164
}
165165
}
166+
167+
extension UIImage {
168+
169+
func resized(toMaxSize maxSize: CGFloat = 1000.0) -> UIImage? {
170+
guard let image = self.normalizedImage() else { return nil }
171+
172+
let width = image.size.width
173+
let height = image.size.height
174+
let aspectRatio = width / height
175+
176+
var newWidth: CGFloat
177+
var newHeight: CGFloat
178+
179+
if width <= height {
180+
// Portrait or square
181+
newHeight = min(height, maxSize)
182+
newWidth = newHeight * aspectRatio
183+
if newWidth > maxSize {
184+
newWidth = maxSize
185+
newHeight = newWidth / aspectRatio
186+
}
187+
} else {
188+
// Landscape
189+
newWidth = min(width, maxSize)
190+
newHeight = newWidth / aspectRatio
191+
if newHeight > maxSize {
192+
newHeight = maxSize
193+
newWidth = newHeight * aspectRatio
194+
}
195+
}
196+
197+
let newSize = CGSize(width: newWidth, height: newHeight)
198+
UIGraphicsBeginImageContextWithOptions(newSize, false, image.scale)
199+
defer { UIGraphicsEndImageContext() }
200+
201+
image.draw(in: CGRect(origin: .zero, size: newSize))
202+
return UIGraphicsGetImageFromCurrentImageContext()
203+
}
204+
205+
/// `Re-orientate` the image to `up`.
206+
func normalizedImage() -> UIImage?
207+
{
208+
if self.imageOrientation == .up
209+
{
210+
return self
211+
}
212+
else
213+
{
214+
UIGraphicsBeginImageContextWithOptions(self.size, false, self.scale)
215+
defer
216+
{
217+
UIGraphicsEndImageContext()
218+
}
219+
220+
self.draw(in: CGRect(origin: .zero, size: self.size))
221+
222+
return UIGraphicsGetImageFromCurrentImageContext()
223+
}
224+
}
225+
}

Sources/Model/OFF/Product.swift

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ public struct Product: Codable, Equatable, Sendable {
6161
public let novaGroup: Double?
6262
public let nutriScore: String?
6363

64-
enum CodingKeys: String, CodingKey {
64+
public enum CodingKeys: String, CodingKey {
6565
case code
6666
case lang
6767
case brands
@@ -85,6 +85,29 @@ public struct Product: Codable, Equatable, Sendable {
8585
case keywords = "_keywords"
8686
}
8787

88+
public init(code: String, productName: String? = nil, productNameEn: String? = nil, brands: String? = nil, lang: OpenFoodFactsLanguage = .ENGLISH, quantity: String? = nil, packagingQuantity: Double = 100, packagingQuantityUnit: String = "g", servingSize: String? = nil, servingQuantity: Double = 100, servingQuantityUnit: String = "g", dataPer: String? = nil, categories: String? = nil, nutriments: [String: Any]? = nil, imageFront: String? = nil, imageIngredients: String? = nil, imageNutrition: String? = nil, keywords: [String]? = nil, novaGroup: Double? = nil, nutriScore: String? = nil) {
89+
self.code = code
90+
self.productName = productName
91+
self.productNameEn = productNameEn
92+
self.brands = brands
93+
self.lang = lang
94+
self.quantity = quantity
95+
self.packagingQuantity = packagingQuantity
96+
self.packagingQuantityUnit = packagingQuantityUnit
97+
self.servingSize = servingSize
98+
self.servingQuantity = servingQuantity
99+
self.servingQuantityUnit = servingQuantityUnit
100+
self.dataPer = dataPer
101+
self.categories = categories
102+
self.nutriments = nutriments
103+
self.imageFront = imageFront
104+
self.imageIngredients = imageIngredients
105+
self.imageNutrition = imageNutrition
106+
self.keywords = keywords
107+
self.novaGroup = novaGroup
108+
self.nutriScore = nutriScore
109+
}
110+
88111
public init(from decoder: Decoder) throws {
89112
let container = try decoder.container(keyedBy: CodingKeys.self)
90113
code = try container.decode(String.self, forKey: .code)

Sources/Model/OFF/SendImage.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,13 @@ public enum ImageField: String, CaseIterable, Decodable {
2828

2929
public struct SendImage {
3030

31-
var barcode: String
32-
var image: UIImage
33-
var imageField: ImageField
31+
public var barcode: String
32+
public var image: UIImage
33+
public var imageField: ImageField
3434

35-
var imageUri: String?
35+
public var imageUri: String?
3636

37-
init(barcode: String, imageField: ImageField = .front, image: UIImage, imageUri: String? = nil) {
37+
public init(barcode: String, imageField: ImageField = .front, image: UIImage, imageUri: String? = nil) {
3838
self.barcode = barcode
3939
self.image = image
4040
self.imageField = imageField

Sources/Networking/HttpHelper.swift

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,7 @@ final class HttpHelper {
7272
data.append("\(value)\r\n")
7373
}
7474

75-
// Files
76-
if let fileData = sendImage.image.pngData() {
75+
if let fileData = sendImage.image.resized()?.jpegData(compressionQuality: 0.8) {
7776
data.append("--\(boundary)\r\n")
7877
data.append("Content-Disposition: form-data; name=\"\(sendImage.getImageDataKey())\"; filename=\"\(fileData.hashValue)\"\r\n")
7978
data.append("Content-Type: application/octet-stream\r\n\r\n")
@@ -90,6 +89,7 @@ final class HttpHelper {
9089
let (data, _) = try await URLSession.shared.data(for: request)
9190
return data
9291
} catch {
92+
print("\(#function) \(uri) error: \(error)")
9393
throw error
9494
}
9595
}
@@ -140,6 +140,7 @@ final class HttpHelper {
140140
return data
141141
} catch {
142142
// Re-throw the error to be caught by the caller
143+
print("\(#function) \(uri) error: \(error)")
143144
throw error
144145
}
145146
}

Sources/Networking/UriHelper.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ final class UriHelper {
2525

2626
var components = URLComponents()
2727
components.scheme = OFFApi.scheme
28-
components.host = OFFConfig.shared.api.host(for: .world)
28+
components.host = OFFConfig.shared.api.host(for: .none)
2929
components.path = path
3030
components.queryItems = allQueryParams?.map { URLQueryItem(name: $0.key, value: $0.value) }
3131

Sources/OFFApi.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ public struct OFFApi {
4141
case images
4242
case events
4343
case taxonomies
44+
case none
4445
}
4546

4647
func host(for endpoint: Endpoint) -> String {
@@ -64,8 +65,12 @@ public struct OFFApi {
6465
subdomain = "static"
6566
case .events:
6667
subdomain = "events"
68+
case .none:
69+
subdomain = ""
6770
}
6871

72+
if subdomain.isEmpty { return domain }
73+
6974
return "\(subdomain).\(domain)"
7075
}
7176
}

Sources/ProductPage.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,6 @@ public struct ProductPage: View {
121121
}))
122122
})
123123
.onAppear(perform: {
124-
UIApplication.shared.addTapGestureRecognizer()
125124
Task(priority: .userInitiated) {
126125
await pageConfig.fetchData(barcode: barcode)
127126
}

Sources/ViewModels/ProductPageConfig.swift

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -172,25 +172,21 @@ final class ProductPageConfig: ObservableObject {
172172
}
173173
}
174174

175+
@MainActor
175176
func uploadAllProductData(barcode: String) async {
176177

177-
await MainActor.run {
178-
self.pageState = .loading
179-
}
178+
self.pageState = .loading
180179

181180
await sendAllImages(barcode: barcode)
182181
do {
183182
let productBody = try await composeProductBody(barcode: barcode)
184183
try await OpenFoodAPIClient.shared.saveProduct(product: productBody)
185184
let productResponse = try await OpenFoodAPIClient.shared.getProduct(config: ProductQueryConfiguration(barcode: barcode))
186-
await MainActor.run {
187-
self.pageState = .completed
188-
}
185+
186+
self.pageState = .completed
189187
try await Task.sleep(nanoseconds: 1_000_000_000 * UInt64(PageOverlay.completedAnimDuration))
190-
await MainActor.run {
191-
self.pageState = ProductPageState.productDetails
192-
self.submittedProduct = productResponse.product
193-
}
188+
self.pageState = ProductPageState.productDetails
189+
self.submittedProduct = productResponse.product
194190
} catch {
195191
await MainActor.run {
196192
self.pageState = .error

0 commit comments

Comments
 (0)