Skip to content

Commit

Permalink
Some more issues fixed
Browse files Browse the repository at this point in the history
  • Loading branch information
hrabkin committed Dec 28, 2023
1 parent 7601c83 commit 2afb905
Show file tree
Hide file tree
Showing 7 changed files with 65 additions and 23 deletions.
2 changes: 1 addition & 1 deletion Example/ExampleCodeFromScanner/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ struct ContentView: View {
BarcodeScannerScreen(barcode: $barcode, isCapturing: $isScanning).ignoresSafeArea(.all)
.navigationDestination(isPresented: $isEditing, destination: {
ProductPage(barcode: barcode) { uploadedProduct in
print(uploadedProduct ?? "")
print(uploadedProduct?.json() ?? "returned product is nil")
}.onDisappear() {
resetState()
}
Expand Down
4 changes: 2 additions & 2 deletions Example/ExampleWithCode/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ struct ContentView: View {
}.padding()
// Added for testing that editor is loaded with NavigatorView
NavigationLink("Check") {
ProductPage(barcode: self.barcode) { product in
print(product.json())
ProductPage(barcode: self.barcode) { uploadedProduct in
print(uploadedProduct?.json() ?? "returned product is nil")
}
}.disabled(!isValidBarcode)
Spacer()
Expand Down
21 changes: 11 additions & 10 deletions Sources/Extensions/Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -111,22 +111,23 @@ extension UIImage {
}
}

public extension [String: String]? {

public func json() -> String {
guard let dictionary = self else {
return "Product is nil"
}

public extension Product {
func json() -> String {
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
do {
let data = try JSONSerialization.data(withJSONObject: dictionary, options: [])
return String(data: data, encoding: .utf8) ?? "Empty"
let jsonData = try encoder.encode(self)
if let jsonString = String(data: jsonData, encoding: .utf8) {
return jsonString
}
return "Couldn't encode json string from the data"
} catch {
return "Error serializing product: \(error)"
return "Error while encoding Product to JSON: \(error)"
}
}
}


public extension [String: String] {

public func json() -> String {
Expand Down
38 changes: 37 additions & 1 deletion Sources/Model/OFF/Product.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public enum DataFor: String {
}
}

public struct Product: Decodable, Equatable {
public struct Product: Codable, Equatable {

public static func == (lhs: Product, rhs: Product) -> Bool {
return lhs.code == rhs.code &&
Expand Down Expand Up @@ -96,6 +96,37 @@ public struct Product: Decodable, Equatable {
self.lang = OpenFoodFactsLanguage.UNDEFINED
}
}

public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(code, forKey: .code)
try container.encodeIfPresent(brands, forKey: .brands)
try container.encodeIfPresent(productName, forKey: .productName)
try container.encodeIfPresent(quantity, forKey: .quantity)
try container.encodeIfPresent(servingSize, forKey: .servingSize)
try container.encodeIfPresent(dataPer, forKey: .dataPer)
try container.encodeIfPresent(categories, forKey: .categories)
try container.encodeIfPresent(imageFront, forKey: .imageFront)
try container.encodeIfPresent(imageIngredients, forKey: .imageIngredients)
try container.encodeIfPresent(imageNutrition, forKey: .imageNutrition)

if let nutriments = self.nutriments {
var nutrimentsContainer = container.nestedContainer(keyedBy: AnyCodingKey.self, forKey: .nutriments)
for (key, value) in nutriments {
let key = AnyCodingKey(stringValue: key)!
switch value {
case let doubleValue as Double:
try nutrimentsContainer.encode(doubleValue, forKey: key)
case let stringValue as String:
try nutrimentsContainer.encode(stringValue, forKey: key)
default:
break
}
}
}

try container.encodeIfPresent(lang?.info.code, forKey: .lang)
}
}

private struct AnyCodingKey: CodingKey {
Expand All @@ -109,4 +140,9 @@ private struct AnyCodingKey: CodingKey {
init?(intValue: Int) {
return nil
}

init(_ key: CodingKey) {
self.stringValue = key.stringValue
self.intValue = key.intValue
}
}
8 changes: 4 additions & 4 deletions Sources/ProductPage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,6 @@ public struct ProductPage: View {
errorMessage: $pageConfig.errorMessage
).ignoresSafeArea()
})
.onChange(of: pageConfig.submittedProduct) { newValue in
self.onUploadingDone(newValue)
dismiss()
}
.toolbar {
ToolbarItem(placement: .topBarLeading) {
Button("Cancel") {
Expand All @@ -112,6 +108,10 @@ public struct ProductPage: View {
}
}
.navigationBarBackButtonHidden()
.onChange(of: pageConfig.submittedProduct) { newValue in
self.onUploadingDone(newValue)
dismiss()
}
.alert(item: $pageConfig.errorMessage, content: { alert in
Alert(title: Text(alert.title), message: Text(alert.message), dismissButton: .cancel(Text("OK"), action: {
self.pageConfig.errorMessage = nil
Expand Down
8 changes: 6 additions & 2 deletions Sources/ViewModels/ProductPageConfig.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ final class ProductPageConfig: ObservableObject {
return pageType == .new
}

// FIXME: move MainActor on class itself

func fetchData(barcode: String) async {

await MainActor.run {
Expand All @@ -88,6 +90,7 @@ final class ProductPageConfig: ObservableObject {
self.isInitialised = true
self.pageType = pageType
}
// FIXME: find a way to show animation states without such workarounds
try await Task.sleep(nanoseconds: 1_000_000_000 * UInt64(PageOverlay.completedAnimDuration))
await MainActor.run {
self.pageState = .productDetails
Expand Down Expand Up @@ -184,17 +187,18 @@ final class ProductPageConfig: ObservableObject {
self.pageState = .loading
}

async let _ = sendAllImages(barcode: barcode)
await sendAllImages(barcode: barcode)
do {
let productBody = try await composeProductBody(barcode: barcode)
try await OpenFoodAPIClient.shared.saveProduct(product: productBody)
let productResponse = try await OpenFoodAPIClient.shared.getProduct(config: ProductQueryConfiguration(barcode: barcode))
await MainActor.run {
self.pageState = .completed
}
try await Task.sleep(nanoseconds: 1_000_000_000 * UInt64(PageOverlay.completedAnimDuration))
await MainActor.run {
self.pageState = ProductPageState.productDetails
self.submittedProduct = productBody.convertToProduct()
self.submittedProduct = productResponse.product
}
} catch {
await MainActor.run {
Expand Down
7 changes: 4 additions & 3 deletions Sources/Views/ImagePickerCropper/Cropper/ImageCropper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,16 @@ class Coordinator: NSObject, CropViewControllerDelegate {
}

func cropViewController(_ cropViewController: CropViewController, didCropToImage image: UIImage, withRect cropRect: CGRect, angle: Int) {
withAnimation {
parent.isPresented = false
}

// FIXME: it doesn't work, image has original size
if (!image.isPictureBigEnough()) {
parent.errorMessage = ErrorAlert(message: "Invalid image", title: "The image is too small! Minimum WxH 640x160")
} else {
self.parent.image = image
}
withAnimation {
parent.isPresented = false
}
}

func cropViewController(_ cropViewController: CropViewController, didFinishCancelled cancelled: Bool) {
Expand Down

0 comments on commit 2afb905

Please sign in to comment.