diff --git a/PadelClub/Data/Coredata/PadelClubApp.xcdatamodeld/Model_1_1.xcdatamodel/contents b/PadelClub/Data/Coredata/PadelClubApp.xcdatamodeld/Model_1_1.xcdatamodel/contents index 8d2cb42..baf1685 100644 --- a/PadelClub/Data/Coredata/PadelClubApp.xcdatamodeld/Model_1_1.xcdatamodel/contents +++ b/PadelClub/Data/Coredata/PadelClubApp.xcdatamodeld/Model_1_1.xcdatamodel/contents @@ -1,5 +1,5 @@ - + diff --git a/PadelClub/Data/Coredata/Persistence.swift b/PadelClub/Data/Coredata/Persistence.swift index 3cfd69b..3bccbff 100644 --- a/PadelClub/Data/Coredata/Persistence.swift +++ b/PadelClub/Data/Coredata/Persistence.swift @@ -17,6 +17,20 @@ class PersistenceController: NSObject { } private static var _model: NSManagedObjectModel? + + static func getModelVersion() -> String? { + if let versions = _model?.versionIdentifiers { + let currentVersion = versions.compactMap { $0 as? String }.joined(separator: ",") + + //print("Current Model Version: \(currentVersion)") + // Compare the current model version with the saved version + return currentVersion + } + + return nil + } + + private static func model(name: String) throws -> NSManagedObjectModel { if _model == nil { _model = try loadModel(name: name, bundle: Bundle.main) @@ -47,10 +61,17 @@ class PersistenceController: NSObject { let fileManager = FileManager.default var firstLaunch = false - if fileManager.fileExists(atPath: localStoreFolderURL.path()) == false { + if fileManager.fileExists(atPath: localStoreFolderURL.appendingPathComponent("local.sqlite").path) == false { firstLaunch = true } + do { + let contents = try fileManager.contentsOfDirectory(atPath: localStoreFolderURL.path) + print("Directory contents: \(contents)") + } catch { + print("Failed to list directory contents: \(error)") + } + for folderURL in [localStoreFolderURL] where !fileManager.fileExists(atPath: folderURL.path) { do { try fileManager.createDirectory(at: folderURL, withIntermediateDirectories: true, attributes: nil) diff --git a/PadelClub/Data/MonthData.swift b/PadelClub/Data/MonthData.swift index 9be70f5..676ccd6 100644 --- a/PadelClub/Data/MonthData.swift +++ b/PadelClub/Data/MonthData.swift @@ -26,16 +26,14 @@ final class MonthData : ModelObject, Storable { var femaleCount: Int? = nil var anonymousCount: Int? = nil var incompleteMode: Bool = false - + var dataModelIdentifier: String? + var fileModelIdentifier: String? + init(monthKey: String) { self.monthKey = monthKey self.creationDate = Date() } - fileprivate func _updateCreationDate() { - self.creationDate = Date() - } - required init(from decoder: Decoder) throws { let container = try decoder.container(keyedBy: CodingKeys.self) id = try container.decode(String.self, forKey: ._id) @@ -47,6 +45,8 @@ final class MonthData : ModelObject, Storable { femaleCount = try container.decodeIfPresent(Int.self, forKey: ._femaleCount) anonymousCount = try container.decodeIfPresent(Int.self, forKey: ._anonymousCount) incompleteMode = try container.decodeIfPresent(Bool.self, forKey: ._incompleteMode) ?? false + dataModelIdentifier = try container.decodeIfPresent(String.self, forKey: ._dataModelIdentifier) ?? nil + fileModelIdentifier = try container.decodeIfPresent(String.self, forKey: ._fileModelIdentifier) ?? nil } @@ -69,7 +69,8 @@ final class MonthData : ModelObject, Storable { await MainActor.run { let lastDataSource = URL.importDateFormatter.string(from: fromDate) let currentMonthData : MonthData = DataStore.shared.monthData.first(where: { $0.monthKey == lastDataSource }) ?? MonthData(monthKey: lastDataSource) - currentMonthData._updateCreationDate() + currentMonthData.dataModelIdentifier = PersistenceController.getModelVersion() + currentMonthData.fileModelIdentifier = fileURL?.fileModelIdentifier() currentMonthData.maleUnrankedValue = incompleteMode ? fftImportingMaleUnrankValue : lastDataSourceMaleUnranked?.0 currentMonthData.incompleteMode = incompleteMode currentMonthData.maleCount = incompleteMode ? fftImportingUncomplete : lastDataSourceMaleUnranked?.1 @@ -97,5 +98,7 @@ final class MonthData : ModelObject, Storable { case _femaleCount = "femaleCount" case _anonymousCount = "anonymousCount" case _incompleteMode = "incompleteMode" + case _dataModelIdentifier = "dataModelIdentifier" + case _fileModelIdentifier = "fileModelIdentifier" } } diff --git a/PadelClub/Extensions/URL+Extensions.swift b/PadelClub/Extensions/URL+Extensions.swift index 3fb7746..f3cce59 100644 --- a/PadelClub/Extensions/URL+Extensions.swift +++ b/PadelClub/Extensions/URL+Extensions.swift @@ -107,6 +107,24 @@ extension URL { return nil } + func fileModelIdentifier() -> String? { + // Read the contents of the file + guard let fileContents = try? String(contentsOfFile: path(), encoding: .utf8) else { + return nil + } + + // Split the contents by newline characters + let lines = fileContents.components(separatedBy: .newlines) + + if let line = lines.first(where: { + $0.hasPrefix("file-model-version:") + }) { + return line.replacingOccurrences(of: "file-model-version:", with: "") + } + + return nil + } + func fftImportingUncomplete() -> Int? { // Read the contents of the file guard let fileContents = try? String(contentsOfFile: path(), encoding: .utf8) else { diff --git a/PadelClub/PadelClubApp.swift b/PadelClub/PadelClubApp.swift index 38c1215..6e48753 100644 --- a/PadelClub/PadelClubApp.swift +++ b/PadelClub/PadelClubApp.swift @@ -76,6 +76,7 @@ struct PadelClubApp: App { .onAppear { networkMonitor.checkConnection() self._onAppear() + print(PersistenceController.getModelVersion()) } .task { diff --git a/PadelClub/Utils/SourceFileManager.swift b/PadelClub/Utils/SourceFileManager.swift index a04a2b7..917c1b4 100644 --- a/PadelClub/Utils/SourceFileManager.swift +++ b/PadelClub/Utils/SourceFileManager.swift @@ -225,6 +225,25 @@ class SourceFileManager { return importDate.isEarlierThan(date) } + + static func getSortOption() -> [SortOption] { + if canFilterByAge() { + return SortOption.allCases + } else { + return [.name, .rank, .tournamentCount, .points] + } + } + + static func canFilterByAge() -> Bool { + let currentMonthData = DataStore.shared.monthData.first(where: { data in + data.monthKey == DataStore.shared.appSettings.lastDataSource + }) + let currentModelVersion = PersistenceController.getModelVersion() + if let currentMonthData, currentMonthData.fileModelIdentifier == currentModelVersion, currentModelVersion != nil { + return true + } + return false + } } enum SourceFile: String, CaseIterable { diff --git a/PadelClub/ViewModel/SearchViewModel.swift b/PadelClub/ViewModel/SearchViewModel.swift index 43aa224..ddb8123 100644 --- a/PadelClub/ViewModel/SearchViewModel.swift +++ b/PadelClub/ViewModel/SearchViewModel.swift @@ -421,16 +421,23 @@ enum DataSet: Int, Identifiable { } var tokens: [SearchToken] { + var _tokens : [SearchToken] = [] switch self { case .national: - return [.club, .ligue, .rankMoreThan, .rankLessThan, .rankBetween, .age] + _tokens = [.club, .ligue, .rankMoreThan, .rankLessThan, .rankBetween] case .ligue: - return [.club, .rankMoreThan, .rankLessThan, .rankBetween, .age] + _tokens = [.club, .rankMoreThan, .rankLessThan, .rankBetween] case .club: - return [.rankMoreThan, .rankLessThan, .rankBetween, .age] + _tokens = [.rankMoreThan, .rankLessThan, .rankBetween] case .favoritePlayers, .favoriteClubs: - return [.rankMoreThan, .rankLessThan, .rankBetween, .age] + _tokens = [.rankMoreThan, .rankLessThan, .rankBetween] } + + if SourceFileManager.canFilterByAge() { + _tokens.append(.age) + } + + return _tokens } } diff --git a/PadelClub/Views/Navigation/MainView.swift b/PadelClub/Views/Navigation/MainView.swift index 047c121..59549d9 100644 --- a/PadelClub/Views/Navigation/MainView.swift +++ b/PadelClub/Views/Navigation/MainView.swift @@ -257,11 +257,14 @@ struct MainView: View { if let current = monthData.last { Task { let updated = await SourceFileManager.shared.fetchData(fromDate: mostRecentDateImported) + let fileURL = SourceFileManager.shared.allFiles(true).first(where: { $0.dateFromPath == mostRecentDateImported && $0.index == 0 }) print("file updated", updated) if let updated, updated == 1 { await _startImporting(importingDate: mostRecentDateImported) } else if current.incompleteMode == false || updated == 0 { await _calculateMonthData(dataSource: current.monthKey) + } else if current.dataModelIdentifier != PersistenceController.getModelVersion() && current.dataModelIdentifier != fileURL?.fileModelIdentifier() { + await _startImporting(importingDate: mostRecentDateImported) } } } diff --git a/PadelClub/Views/Shared/SelectablePlayerListView.swift b/PadelClub/Views/Shared/SelectablePlayerListView.swift index 45025ec..b0f195d 100644 --- a/PadelClub/Views/Shared/SelectablePlayerListView.swift +++ b/PadelClub/Views/Shared/SelectablePlayerListView.swift @@ -74,7 +74,7 @@ struct SelectablePlayerListView: View { .pickerStyle(.segmented) Menu { Section { - ForEach(SortOption.allCases) { option in + ForEach(SourceFileManager.getSortOption()) { option in Toggle(isOn: .init(get: { return searchViewModel.sortOption == option }, set: { value in @@ -90,19 +90,22 @@ struct SelectablePlayerListView: View { Text("Trier par") } Divider() - Section { - Picker(selection: $searchViewModel.selectedAgeCategory) { - ForEach(FederalTournamentAge.allCases) { ageCategory in - Text(ageCategory.localizedLabel(.title)).tag(ageCategory) + + if SourceFileManager.canFilterByAge() { + Section { + Picker(selection: $searchViewModel.selectedAgeCategory) { + ForEach(FederalTournamentAge.allCases) { ageCategory in + Text(ageCategory.localizedLabel(.title)).tag(ageCategory) + } + } label: { + Text("Catégorie d'âge") } - } label: { + + } header: { Text("Catégorie d'âge") } - - } header: { - Text("Catégorie d'âge") + Divider() } - Divider() Section { Toggle(isOn: .init(get: { return searchViewModel.hideAssimilation == false