Skip to content
This repository has been archived by the owner on Sep 5, 2023. It is now read-only.

Commit

Permalink
WIP: Taxonomy model for Label is not correct, estimated design from C…
Browse files Browse the repository at this point in the history
…ategory.swift
  • Loading branch information
jncosideout committed Aug 23, 2020
1 parent 0d8a43a commit e896c8e
Show file tree
Hide file tree
Showing 6 changed files with 116 additions and 2 deletions.
49 changes: 49 additions & 0 deletions Sources/Models/API/Taxonomies/Label.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
//
// Label.swift
// OpenFoodFacts
//
// Created by Alexander Scott Beaty on 8/23/20.
//

import Foundation
import RealmSwift
import ObjectMapper

class Label: Object {

@objc dynamic var code = ""

let parents = List<String>()
let children = List<String>()
let names = List<Tag>()

@objc dynamic var mainName = "" // name in the language of the app, for sorting
@objc dynamic var indexedNames = "" // all names concatenated, for search

convenience init(code: String, parents: [String], children: [String], names: [Tag]) {
self.init()
self.code = code

self.parents.removeAll()
self.parents.append(objectsIn: parents)

self.children.removeAll()
self.children.append(objectsIn: children)

self.names.removeAll()
self.names.append(objectsIn: names)

self.mainName = names.chooseForCurrentLanguage()?.value ?? ""
self.indexedNames = names.map({ (tag) -> String in
return tag.languageCode.appending(":").appending(tag.value)
}).joined(separator: " ||| ") // group all names to be able to query on only one field, independently of language
}

override static func primaryKey() -> String? {
return "code"
}

override static func indexedProperties() -> [String] {
return ["mainName", "indexedNames"]
}
}
17 changes: 17 additions & 0 deletions Sources/Models/PersistenceManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ protocol PersistenceManagerProtocol {
func save(tagLine: Tagline)
func tagLine() -> Tagline?
var additivesIsEmpty: Bool { get }

func save(labels: [Label])
func label(forCode: String) -> Label?

// Offline
func save(offlineProducts: [RealmOfflineProduct])
Expand Down Expand Up @@ -365,6 +368,20 @@ class PersistenceManager: PersistenceManagerProtocol {
return getRealm().object(ofType: IngredientsAnalysisConfig.self, forPrimaryKey: code)
}

func save(labels: [Label]) {
saveOrUpdate(objects: labels)
log.info("Saved \(labels.count) labels in taxonomy database")
}

func label(forCode code: String) -> Label? {
return getRealm().object(ofType: Label.self, forPrimaryKey: code)
}

var labelsIsEmpty: Bool {
getRealm().objects(Label.self).isEmpty
}

// Offline Products
func save(offlineProducts: [RealmOfflineProduct]) {
saveOrUpdate(objects: offlineProducts)
}
Expand Down
13 changes: 13 additions & 0 deletions Sources/Network/TaxonomiesParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,19 @@ struct TaxonomiesParser: TaxonomiesParserProtocol {
})
return ingredientsAnalysisConfig
}

func parseLabels(data: [String: Any]) -> [Label] {
let labels = data.compactMap({ (labelCode: String, value: Any) -> Label? in
let tags = parseTags(value: value)
let parents = parseParents(value: value)
let children = parseChildren(value: value)
return Label(code: labelCode,
parents: parents,
children: children,
names: tags)
})
return labels
}

// MARK: - Private Helper Methods

Expand Down
31 changes: 29 additions & 2 deletions Sources/Network/TaxonomiesService.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ enum TaxonomiesRoute: String {
case getMinerals = "taxonomies/minerals.json"
case getNucleotides = "taxonomies/nucleotides.json"
case getInvalidBarcodes = "invalid-barcodes.json"
case getLabels = "taxonomies/labels.json"
}

enum FilesRouter: URLRequestConvertible {
Expand Down Expand Up @@ -356,7 +357,28 @@ class TaxonomiesService: TaxonomiesApi {
callback(false)
}
}


fileprivate func refreshLabels(_ callback: @escaping (_: Bool) -> Void) {
do {
let request = try TaxonomiesRequest(route: .getLabels, requestType: .get).asURLRequest()
Alamofire.request(request)
.responseJSON { (response) in
switch response.result {
case .success(let responseBody):
if let json = responseBody as? [String: Any] {
let labels = self.taxonomiesParser.parseLabels(data: json)
self.persistenceManager.save(labels: labels)
callback(true)
}
case .failure(let error):
AnalyticsManager.record(error: error)
callback(false)
}
}
} catch {
callback(false)
}
}
// swiftlint:disable identifier_name

/// increment last number each time you want to force a refresh. Useful if you add a new refresh method or a new field
Expand Down Expand Up @@ -454,11 +476,16 @@ class TaxonomiesService: TaxonomiesApi {
})

group.enter()

self.refreshInvalidBarcodes { (success) in
allSuccess = allSuccess && success
group.leave()
}

group.enter()
self.refreshLabels({ (success) in
allSuccess = allSuccess && success
group.leave()
})

group.wait()

Expand Down
1 change: 1 addition & 0 deletions Sources/Protocols/TaxonomiesParserProtocol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ protocol TaxonomiesParserProtocol {
func parseAdditives(data: [String: Any]) -> [Additive]
func parseIngredientsAnalysis(data: [String: Any]) -> [IngredientsAnalysis]
func parseIngredientsAnalysisConfig(data: [String: Any]) -> [IngredientsAnalysisConfig]
func parseLabels(data: [String: Any]) -> [Label]
}
7 changes: 7 additions & 0 deletions Tests/Models/PersistenceManagerMock.swift
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,13 @@ class PersistenceManagerMock: PersistenceManagerProtocol {
return nil
}

func save(labels: [Label]) {
}

func label(forCode: String) -> Label? {
return nil
}

func save(offlineProducts: [RealmOfflineProduct]) {
}

Expand Down

0 comments on commit e896c8e

Please sign in to comment.