diff --git a/.github/workflows/download_onesky_translations.yml b/.github/workflows/download_onesky_translations.yml index acfa59b3c1..56a740ce31 100644 --- a/.github/workflows/download_onesky_translations.yml +++ b/.github/workflows/download_onesky_translations.yml @@ -53,3 +53,4 @@ jobs: branch: 'latest-onesky-translations' token: ${{ secrets.CREATE_PULL_REQUEST_ACCESS_TOKEN }} title: 'Latest OneSky Translations' + add-paths: godtools/* diff --git a/Gemfile.lock b/Gemfile.lock index 2ed28c2b34..51f5292675 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -24,20 +24,20 @@ GEM artifactory (3.0.17) atomos (0.1.3) aws-eventstream (1.3.0) - aws-partitions (1.975.0) - aws-sdk-core (3.205.0) + aws-partitions (1.981.0) + aws-sdk-core (3.209.1) aws-eventstream (~> 1, >= 1.3.0) aws-partitions (~> 1, >= 1.651.0) aws-sigv4 (~> 1.9) jmespath (~> 1, >= 1.6.1) - aws-sdk-kms (1.91.0) - aws-sdk-core (~> 3, >= 3.205.0) + aws-sdk-kms (1.94.0) + aws-sdk-core (~> 3, >= 3.207.0) aws-sigv4 (~> 1.5) - aws-sdk-s3 (1.162.0) - aws-sdk-core (~> 3, >= 3.205.0) + aws-sdk-s3 (1.166.0) + aws-sdk-core (~> 3, >= 3.207.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.5) - aws-sigv4 (1.9.1) + aws-sigv4 (1.10.0) aws-eventstream (~> 1, >= 1.0.2) babosa (1.0.4) base64 (0.2.0) @@ -97,7 +97,7 @@ GEM ethon (0.16.0) ffi (>= 1.15.0) excon (0.111.0) - faraday (1.10.3) + faraday (1.10.4) faraday-em_http (~> 1.0) faraday-em_synchrony (~> 1.0) faraday-excon (~> 1.1) @@ -123,10 +123,10 @@ GEM faraday-patron (1.0.0) faraday-rack (1.0.0) faraday-retry (1.0.3) - faraday_middleware (1.2.0) + faraday_middleware (1.2.1) faraday (~> 1.0) fastimage (2.3.1) - fastlane (2.222.0) + fastlane (2.223.1) CFPropertyList (>= 2.3, < 4.0.0) addressable (>= 2.8, < 3.0.0) artifactory (~> 3.0) @@ -220,7 +220,7 @@ GEM concurrent-ruby (~> 1.0) jmespath (1.6.2) json (2.7.2) - jwt (2.9.0) + jwt (2.9.1) base64 logger (1.6.1) mime-types (3.5.2) @@ -254,7 +254,7 @@ GEM mime-types (>= 1.16, < 4.0) netrc (~> 0.8) retriable (3.1.2) - rexml (3.3.7) + rexml (3.3.8) rouge (2.0.7) ruby-macho (2.5.1) ruby2_keywords (0.0.5) diff --git a/godtools.xcodeproj/project.pbxproj b/godtools.xcodeproj/project.pbxproj index cfe9315543..5fc1e078bc 100644 --- a/godtools.xcodeproj/project.pbxproj +++ b/godtools.xcodeproj/project.pbxproj @@ -1605,8 +1605,6 @@ D4E7EE052C780C8800F75DA6 /* LinkShareable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4EEB67C2C75371E006F0D39 /* LinkShareable.swift */; }; D4EAF2F92C0F95D900AEC36C /* UserToolSettingsRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4EAF2F82C0F95D900AEC36C /* UserToolSettingsRepository.swift */; }; D4EEB67B2C7518AF006F0D39 /* ConfirmAppLanguageHighlightStringDomainModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4EEB67A2C7518AF006F0D39 /* ConfirmAppLanguageHighlightStringDomainModel.swift */; }; - D4EFC9632B49B28200B0D34A /* LanguageDownloadErrorAlertView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4EFC9622B49B28200B0D34A /* LanguageDownloadErrorAlertView.swift */; }; - D4EFC9652B49B29D00B0D34A /* LanguageDownloadErrorAlertViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4EFC9642B49B29D00B0D34A /* LanguageDownloadErrorAlertViewModel.swift */; }; D4F0457B2BBB464D00B115C9 /* RealmUserToolFiltersCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4F0457A2BBB464D00B115C9 /* RealmUserToolFiltersCache.swift */; }; D4F0457D2BBB469A00B115C9 /* RealmUserToolCategoryFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4F0457C2BBB469A00B115C9 /* RealmUserToolCategoryFilter.swift */; }; D4F0457F2BBB479D00B115C9 /* RealmUserToolLanguageFilter.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4F0457E2BBB479D00B115C9 /* RealmUserToolLanguageFilter.swift */; }; @@ -3366,8 +3364,6 @@ D4EAF2F82C0F95D900AEC36C /* UserToolSettingsRepository.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserToolSettingsRepository.swift; sourceTree = ""; }; D4EEB67A2C7518AF006F0D39 /* ConfirmAppLanguageHighlightStringDomainModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConfirmAppLanguageHighlightStringDomainModel.swift; sourceTree = ""; }; D4EEB67C2C75371E006F0D39 /* LinkShareable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinkShareable.swift; sourceTree = ""; }; - D4EFC9622B49B28200B0D34A /* LanguageDownloadErrorAlertView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LanguageDownloadErrorAlertView.swift; sourceTree = ""; }; - D4EFC9642B49B29D00B0D34A /* LanguageDownloadErrorAlertViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LanguageDownloadErrorAlertViewModel.swift; sourceTree = ""; }; D4F0457A2BBB464D00B115C9 /* RealmUserToolFiltersCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RealmUserToolFiltersCache.swift; sourceTree = ""; }; D4F0457C2BBB469A00B115C9 /* RealmUserToolCategoryFilter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RealmUserToolCategoryFilter.swift; sourceTree = ""; }; D4F0457E2BBB479D00B115C9 /* RealmUserToolLanguageFilter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RealmUserToolLanguageFilter.swift; sourceTree = ""; }; @@ -8174,7 +8170,6 @@ 45AC9DE72B28A9CD00DEEBFE /* Subviews */ = { isa = PBXGroup; children = ( - D4EFC9612B49B26200B0D34A /* LanguageDownloadErrorAlertView */, 45AC9DE82B28A9CD00DEEBFE /* DownloadableLanguageItemView.swift */, 45AC9DE92B28A9CD00DEEBFE /* LanguageDownloadIcon.swift */, ); @@ -11251,13 +11246,6 @@ path = Subviews; sourceTree = ""; }; - D40D77BD2AB23183008D3642 /* Models */ = { - isa = PBXGroup; - children = ( - ); - path = Models; - sourceTree = ""; - }; D4159D512C2CE0240088A203 /* PersistUserToolLanguageSettings */ = { isa = PBXGroup; children = ( @@ -11478,7 +11466,6 @@ D40D77B42AA900FB008D3642 /* ToolStringKeys.swift */, 45920D4E2A8D3D1800E336A8 /* ToolsView.swift */, 45920D4D2A8D3D1800E336A8 /* ToolsViewModel.swift */, - D40D77BD2AB23183008D3642 /* Models */, 45DD84C42A8BD53E0066A020 /* Subviews */, ); path = Tools; @@ -11825,15 +11812,6 @@ path = "SwiftUI Modifiers"; sourceTree = ""; }; - D4EFC9612B49B26200B0D34A /* LanguageDownloadErrorAlertView */ = { - isa = PBXGroup; - children = ( - D4EFC9622B49B28200B0D34A /* LanguageDownloadErrorAlertView.swift */, - D4EFC9642B49B29D00B0D34A /* LanguageDownloadErrorAlertViewModel.swift */, - ); - path = LanguageDownloadErrorAlertView; - sourceTree = ""; - }; D4F1DE8E2967539200A2F674 /* IncrementUserCounterUseCase */ = { isa = PBXGroup; children = ( @@ -12473,7 +12451,6 @@ D455F3ED2977302D009D5F93 /* GetUserActivityUseCase.swift in Sources */, 4598BD1B2BF7DF6800196463 /* AccountDomainLayerDependencies.swift in Sources */, D4B060022912C335005852D0 /* MobileContentAuthTokenCache.swift in Sources */, - D4EFC9632B49B28200B0D34A /* LanguageDownloadErrorAlertView.swift in Sources */, 450397332B360F1B00938EE9 /* IdentifiableRealmObject.swift in Sources */, 4534F93E2AE9B11600A7A071 /* LessonEvaluationRepository.swift in Sources */, 450D7B0228E32965006C3FDF /* TrackDownloadedTranslationsCache.swift in Sources */, @@ -13278,7 +13255,6 @@ 458CFE9B29D4E0B9007B423C /* ArticleCategoryCellViewModel.swift in Sources */, D47DF0462B2A3D5D0079219B /* DownloadedLanguageDataModel.swift in Sources */, 45D814D32B81056B00AD00C5 /* SpotlightToolsDiContainer.swift in Sources */, - D4EFC9652B49B29D00B0D34A /* LanguageDownloadErrorAlertViewModel.swift in Sources */, 45C1527F2A44888100F2A1E8 /* LessonEvaluationView.swift in Sources */, 45AF47ED2B35E03500361EA7 /* GetToolSettingsToolHasTipsRepositoryInterface.swift in Sources */, D42FEBDA287604570002FAD9 /* OptInOnboardingBannerEnabledRepository.swift in Sources */, diff --git a/godtools/App/Features/AppLanguage/Data-DomainInterface/DownloadToolLanguageRepository.swift b/godtools/App/Features/AppLanguage/Data-DomainInterface/DownloadToolLanguageRepository.swift index 49990094a0..43c61f96b2 100644 --- a/godtools/App/Features/AppLanguage/Data-DomainInterface/DownloadToolLanguageRepository.swift +++ b/godtools/App/Features/AppLanguage/Data-DomainInterface/DownloadToolLanguageRepository.swift @@ -22,21 +22,37 @@ class DownloadToolLanguageRepository: DownloadToolLanguageRepositoryInterface { self.toolLanguageDownloader = toolLanguageDownloader } - func downloadToolTranslations(for languageId: String, languageCode: BCP47LanguageIdentifier) -> AnyPublisher { + func downloadToolTranslations(for languageId: String, languageCode: BCP47LanguageIdentifier) -> AnyPublisher { downloadedLanguagesRepository.storeDownloadedLanguage(languageId: languageId, downloadComplete: false) return toolLanguageDownloader .downloadToolLanguagePublisher(languageId: languageId) - .map { + .catch { (downloadError: Error) -> AnyPublisher in - let progress = $0.progress + return self.downloadedLanguagesRepository.deleteDownloadedLanguagePublisher(languageId: languageId) + .catch { (deleteError: Error) -> AnyPublisher in + + assertionFailure("Failed to delete object in RealmDatabase. \(deleteError.localizedDescription)") + + return Fail(error: downloadError) + .eraseToAnyPublisher() + } + .flatMap({ (void: Void) -> AnyPublisher in + return Fail(error: downloadError) + .eraseToAnyPublisher() + }) + .eraseToAnyPublisher() + } + .map { (dataModel: ToolDownloaderDataModel) in + + let progress = dataModel.progress if progress >= 1 { self.downloadedLanguagesRepository.storeDownloadedLanguage(languageId: languageId, downloadComplete: true) } - return $0.progress + return dataModel.progress } .eraseToAnyPublisher() } diff --git a/godtools/App/Features/AppLanguage/Data/ToolLanguageDownloader/ToolLanguageDownloader.swift b/godtools/App/Features/AppLanguage/Data/ToolLanguageDownloader/ToolLanguageDownloader.swift index 9feeea43d1..9dae1814f2 100644 --- a/godtools/App/Features/AppLanguage/Data/ToolLanguageDownloader/ToolLanguageDownloader.swift +++ b/godtools/App/Features/AppLanguage/Data/ToolLanguageDownloader/ToolLanguageDownloader.swift @@ -24,19 +24,21 @@ class ToolLanguageDownloader { self.downloadedLanguagesRepository = downloadedLanguagesRepository } - func downloadToolLanguagePublisher(languageId: String) -> AnyPublisher { + func downloadToolLanguagePublisher(languageId: String) -> AnyPublisher { guard let languageModel = languagesRepository.getLanguage(id: languageId) else { - let emptyDownload = ToolDownloaderDataModel(attachments: [], progress: 1, translations: []) + let error: Error = NSError.errorWithDomain(domain: "ToolLanguageDownloader", code: -1, description: "Internal Error in ToolLanguageDownloader. Failed to fetch language with language id: \(languageId)") - return Just(emptyDownload) + return Fail(error: error) .eraseToAnyPublisher() } let includeToolTypes: [ResourceType] = ResourceType.toolTypes + [.lesson] - let tools: [ResourceModel] = resourcesRepository.getCachedResourcesByFilter(filter: ResourcesFilter(category: nil, languageModelCode: languageModel.code, resourceTypes: includeToolTypes)) + let tools: [ResourceModel] = resourcesRepository.getCachedResourcesByFilter( + filter: ResourcesFilter(category: nil, languageModelCode: languageModel.code, resourceTypes: includeToolTypes) + ) let downloadTools: [DownloadToolDataModel] = tools.map({ DownloadToolDataModel(toolId: $0.id, languages: [languageModel.code]) @@ -46,12 +48,12 @@ class ToolLanguageDownloader { .eraseToAnyPublisher() } - func syncDownloadedLanguagesPublisher() -> AnyPublisher { + func syncDownloadedLanguagesPublisher() -> AnyPublisher { return downloadedLanguagesRepository.getDownloadedLanguagesPublisher(completedDownloadsOnly: false) - .flatMap({ (downloadedLanguages: [DownloadedLanguageDataModel]) -> AnyPublisher in + .flatMap({ (downloadedLanguages: [DownloadedLanguageDataModel]) -> AnyPublisher in - let downloadToolLanguageRequests = downloadedLanguages.map({ + let downloadToolLanguageRequests: [AnyPublisher] = downloadedLanguages.map({ self.downloadToolLanguagePublisher(languageId: $0.languageId) }) diff --git a/godtools/App/Features/AppLanguage/Domain/Interface/DownloadToolLanguageRepositoryInterface.swift b/godtools/App/Features/AppLanguage/Domain/Interface/DownloadToolLanguageRepositoryInterface.swift index ad33fd329d..39725a85c1 100644 --- a/godtools/App/Features/AppLanguage/Domain/Interface/DownloadToolLanguageRepositoryInterface.swift +++ b/godtools/App/Features/AppLanguage/Domain/Interface/DownloadToolLanguageRepositoryInterface.swift @@ -11,5 +11,5 @@ import Combine protocol DownloadToolLanguageRepositoryInterface { - func downloadToolTranslations(for languageId: String, languageCode: BCP47LanguageIdentifier) -> AnyPublisher + func downloadToolTranslations(for languageId: String, languageCode: BCP47LanguageIdentifier) -> AnyPublisher } diff --git a/godtools/App/Features/AppLanguage/Domain/UseCases/DownloadToolLanguageUseCase.swift b/godtools/App/Features/AppLanguage/Domain/UseCases/DownloadToolLanguageUseCase.swift index cd190364ac..627bdae133 100644 --- a/godtools/App/Features/AppLanguage/Domain/UseCases/DownloadToolLanguageUseCase.swift +++ b/godtools/App/Features/AppLanguage/Domain/UseCases/DownloadToolLanguageUseCase.swift @@ -18,7 +18,7 @@ class DownloadToolLanguageUseCase { self.downloadToolLanguageRepository = downloadToolLanguageRepository } - func downloadToolLanguage(languageId: String, languageCode: BCP47LanguageIdentifier) -> AnyPublisher { + func downloadToolLanguage(languageId: String, languageCode: BCP47LanguageIdentifier) -> AnyPublisher { return downloadToolLanguageRepository.downloadToolTranslations(for: languageId, languageCode: languageCode) } diff --git a/godtools/App/Features/AppLanguage/Presentation/DownloadableLanguages/Subviews/LanguageDownloadErrorAlertView/LanguageDownloadErrorAlertView.swift b/godtools/App/Features/AppLanguage/Presentation/DownloadableLanguages/Subviews/LanguageDownloadErrorAlertView/LanguageDownloadErrorAlertView.swift deleted file mode 100644 index 695538b171..0000000000 --- a/godtools/App/Features/AppLanguage/Presentation/DownloadableLanguages/Subviews/LanguageDownloadErrorAlertView/LanguageDownloadErrorAlertView.swift +++ /dev/null @@ -1,21 +0,0 @@ -// -// LanguageDownloadErrorAlertView.swift -// godtools -// -// Created by Rachael Skeath on 1/6/24. -// Copyright © 2024 Cru. All rights reserved. -// - -import UIKit - -class LanguageDownloadErrorAlertView: AlertMessageView { - - init(viewModel: LanguageDownloadErrorAlertViewModel) { - - super.init(viewModel: viewModel) - } - - required init(viewModel: AlertMessageViewModelType) { - fatalError("init(viewModel:) has not been implemented") - } -} diff --git a/godtools/App/Features/AppLanguage/Presentation/DownloadableLanguages/Subviews/LanguageDownloadErrorAlertView/LanguageDownloadErrorAlertViewModel.swift b/godtools/App/Features/AppLanguage/Presentation/DownloadableLanguages/Subviews/LanguageDownloadErrorAlertView/LanguageDownloadErrorAlertViewModel.swift deleted file mode 100644 index d8ea05267e..0000000000 --- a/godtools/App/Features/AppLanguage/Presentation/DownloadableLanguages/Subviews/LanguageDownloadErrorAlertView/LanguageDownloadErrorAlertViewModel.swift +++ /dev/null @@ -1,30 +0,0 @@ -// -// LanguageDownloadErrorAlertViewModel.swift -// godtools -// -// Created by Rachael Skeath on 1/6/24. -// Copyright © 2024 Cru. All rights reserved. -// - -import Foundation - -class LanguageDownloadErrorAlertViewModel: AlertMessageViewModelType { - - let title: String? = "Download Error" - let message: String? - let cancelTitle: String? = "Ok" - let acceptTitle: String = "Ok" - - init(error: Error) { - - message = "Try again later. Error: " + error.localizedDescription - } - - deinit { - print("x deinit: \(type(of: self))") - } - - func acceptTapped() { - - } -} diff --git a/godtools/App/Features/Dashboard/Data-DomainInterface/FavoritedToolsLatestToolDownloader.swift b/godtools/App/Features/Dashboard/Data-DomainInterface/FavoritedToolsLatestToolDownloader.swift index 36c2d537e4..c646cd09c7 100644 --- a/godtools/App/Features/Dashboard/Data-DomainInterface/FavoritedToolsLatestToolDownloader.swift +++ b/godtools/App/Features/Dashboard/Data-DomainInterface/FavoritedToolsLatestToolDownloader.swift @@ -54,6 +54,9 @@ class FavoritedToolsLatestToolDownloader: FavoritedToolsLatestToolDownloaderInte .map { _ in return Void() } + .catch { _ in + return Just(Void()) + } .eraseToAnyPublisher() }) .eraseToAnyPublisher() diff --git a/godtools/App/Flows/App/AppFlow.swift b/godtools/App/Flows/App/AppFlow.swift index 8e3ea7b99f..d192b46d39 100644 --- a/godtools/App/Flows/App/AppFlow.swift +++ b/godtools/App/Flows/App/AppFlow.swift @@ -466,16 +466,19 @@ extension AppFlow { resourcesRepository .syncLanguagesAndResourcesPlusLatestTranslationsAndLatestAttachmentsIgnoringErrorPublisher() - .flatMap({ _ -> AnyPublisher in + .setFailureType(to: Error.self) + .flatMap({ (result: RealmResourcesCacheSyncResult) -> AnyPublisher in return self.toolLanguageDownloader .syncDownloadedLanguagesPublisher() .eraseToAnyPublisher() }) .receive(on: DispatchQueue.main) - .sink { _ in + .sink(receiveCompletion: { _ in - } + }, receiveValue: { _ in + + }) .store(in: &cancellables) _ = followUpsService.postFailedFollowUpsIfNeeded() diff --git a/godtools/App/Flows/LanguageSettings/LanguageSettingsFlow.swift b/godtools/App/Flows/LanguageSettings/LanguageSettingsFlow.swift index 737a23582d..d37c29cfc6 100644 --- a/godtools/App/Flows/LanguageSettings/LanguageSettingsFlow.swift +++ b/godtools/App/Flows/LanguageSettings/LanguageSettingsFlow.swift @@ -14,6 +14,8 @@ class LanguageSettingsFlow: Flow, ChooseAppLanguageNavigationFlow { private weak var flowDelegate: FlowDelegate? + @Published private var appLanguage: AppLanguageDomainModel = "" + let appDiContainer: AppDiContainer let navigationController: AppNavigationController @@ -37,6 +39,12 @@ class LanguageSettingsFlow: Flow, ChooseAppLanguageNavigationFlow { sharedNavigationController.pushViewController(initialView, animated: true) } + + appDiContainer.feature.appLanguage.domainLayer + .getCurrentAppLanguageUseCase() + .getLanguagePublisher() + .receive(on: DispatchQueue.main) + .assign(to: &$appLanguage) } deinit { @@ -53,7 +61,7 @@ class LanguageSettingsFlow: Flow, ChooseAppLanguageNavigationFlow { case .chooseAppLanguageTappedFromLanguageSettings: navigateToChooseAppLanguageFlow() - case .chooseAppLanguageFlowCompleted(let state): + case .chooseAppLanguageFlowCompleted( _): navigateBackFromChooseAppLanguageFlow() case .editDownloadedLanguagesTappedFromLanguageSettings: @@ -63,8 +71,7 @@ class LanguageSettingsFlow: Flow, ChooseAppLanguageNavigationFlow { navigationController.popViewController(animated: true) case .showLanguageDownloadErrorAlert(let error): - let alertView = getLanguageDownloadErrorAlertView(error: error) - navigationController.present(alertView, animated: true) + presentError(appLanguage: appLanguage, error: error) default: break @@ -135,12 +142,4 @@ extension LanguageSettingsFlow { return hostingView } - - func getLanguageDownloadErrorAlertView(error: Error) -> UIViewController { - - let viewModel = LanguageDownloadErrorAlertViewModel(error: error) - let view = LanguageDownloadErrorAlertView(viewModel: viewModel) - - return view.controller - } } diff --git a/godtools/App/Share/Data/ToolDownloader/ToolDownloader.swift b/godtools/App/Share/Data/ToolDownloader/ToolDownloader.swift index 358b6024dc..2814deb12c 100644 --- a/godtools/App/Share/Data/ToolDownloader/ToolDownloader.swift +++ b/godtools/App/Share/Data/ToolDownloader/ToolDownloader.swift @@ -27,7 +27,7 @@ class ToolDownloader { self.articleManifestAemRepository = articleManifestAemRepository } - func downloadToolsPublisher(tools: [DownloadToolDataModel]) -> AnyPublisher { + func downloadToolsPublisher(tools: [DownloadToolDataModel]) -> AnyPublisher { var translations: [TranslationModel] = Array() var attachments: [AttachmentModel] = Array() @@ -56,27 +56,23 @@ class ToolDownloader { } } - let translationsAndArticlesRequest: AnyPublisher = + let translationsAndArticlesRequest: AnyPublisher = downloadToolTranslationsAndArticlesRequest(translations: translations) .map { _ in Void() } .eraseToAnyPublisher() - let attachmentsRequests: [AnyPublisher] = attachments + let attachmentsRequests: [AnyPublisher] = attachments .map { (attachment: AttachmentModel) in self.attachmentsRepository.downloadAndCacheAttachmentIfNeeded(attachment: attachment) .map { _ in return Void() } - .catch { (error: Error) in - return Just(Void()) - .eraseToAnyPublisher() - } .eraseToAnyPublisher() } - let requests: [AnyPublisher] = attachmentsRequests + [translationsAndArticlesRequest] + let requests: [AnyPublisher] = attachmentsRequests + [translationsAndArticlesRequest] var downloadCount: Double = 0 @@ -94,43 +90,40 @@ class ToolDownloader { .eraseToAnyPublisher() } - private func downloadToolTranslationsAndArticlesRequest(translations: [TranslationModel]) -> AnyPublisher<[Void], Never> { + private func downloadToolTranslationsAndArticlesRequest(translations: [TranslationModel]) -> AnyPublisher<[Void], Error> { - let requests = translations.map { (translation: TranslationModel) in + let downloadTranslationsRequests = translations.map { (translation: TranslationModel) in self.translationsRepository.downloadAndCacheTranslationFiles(translation: translation) - .catch({ (error: Error) in - return Just(TranslationFilesDataModel(files: [], translation: translation)) - .eraseToAnyPublisher() - }) - .flatMap({ (dataModel: TranslationFilesDataModel) -> AnyPublisher in + .flatMap({ (dataModel: TranslationFilesDataModel) -> AnyPublisher in let resource: ResourceModel? = dataModel.translation.resource let resourceIsArticle: Bool = resource?.resourceTypeEnum == .article - if resourceIsArticle, let languageCode = dataModel.translation.language?.code { + guard resourceIsArticle, let languageCode = dataModel.translation.language?.code else { - return self.downloadArticlesPublisher( - translation: dataModel.translation, - languageCode: languageCode - ) + return Just(Void()) + .setFailureType(to: Error.self) + .eraseToAnyPublisher() } - return Just(Void()) - .eraseToAnyPublisher() + return self.downloadArticlesPublisher( + translation: dataModel.translation, + languageCode: languageCode + ) }) .eraseToAnyPublisher() } - return Publishers.MergeMany(requests) + return Publishers.MergeMany(downloadTranslationsRequests) .collect() .eraseToAnyPublisher() } - private func downloadArticlesPublisher(translation: TranslationModel, languageCode: String) -> AnyPublisher { + private func downloadArticlesPublisher(translation: TranslationModel, languageCode: String) -> AnyPublisher { return translationsRepository .getTranslationManifestFromCache(translation: translation, manifestParserType: .manifestOnly, includeRelatedFiles: false) - .flatMap({ (dataModel: TranslationManifestFileDataModel) -> AnyPublisher in + .flatMap({ (dataModel: TranslationManifestFileDataModel) -> AnyPublisher in return self.articleManifestAemRepository .downloadAndCacheManifestAemUrisPublisher( @@ -138,17 +131,12 @@ class ToolDownloader { languageCode: languageCode, forceDownload: true ) - }) - .flatMap({ (result: ArticleAemRepositoryResult) -> AnyPublisher in - - return Just(Void()) - .eraseToAnyPublisher() - }) - .catch({ (error: Error) in - - return Just(Void()) + .setFailureType(to: Error.self) .eraseToAnyPublisher() }) + .map { _ in + Void() + } .eraseToAnyPublisher() } } diff --git a/godtools/App/Share/Data/TranslationsRepository/TranslationsRepository.swift b/godtools/App/Share/Data/TranslationsRepository/TranslationsRepository.swift index 24ccfdd401..aa627cb745 100644 --- a/godtools/App/Share/Data/TranslationsRepository/TranslationsRepository.swift +++ b/godtools/App/Share/Data/TranslationsRepository/TranslationsRepository.swift @@ -322,7 +322,7 @@ extension TranslationsRepository { func downloadAndCacheTranslationFiles(translation: TranslationModel) -> AnyPublisher { return getTranslationFileFromCacheElseRemote(translation: translation, fileName: translation.manifestName) - .flatMap({ fileCacheLocation -> AnyPublisher in + .flatMap({ (fileCacheLocation: FileCacheLocation) -> AnyPublisher in let manifestParser: TranslationManifestParser = TranslationManifestParser.getManifestParser(type: .manifestOnly, infoPlist: self.infoPlist, resourcesFileCache: self.resourcesFileCache, appBuild: self.appBuild) @@ -331,13 +331,13 @@ extension TranslationsRepository { }) .flatMap({ (manifest: Manifest) -> AnyPublisher in - let requests = manifest.relatedFiles.map { + let requestsForRelatedFiles = manifest.relatedFiles.map { self.getTranslationFileFromCacheElseRemote(translation: translation, fileName: $0) } - return Publishers.MergeMany(requests) + return Publishers.MergeMany(requestsForRelatedFiles) .collect() - .flatMap({ files -> AnyPublisher in + .flatMap({ (files: [FileCacheLocation]) -> AnyPublisher in return self.didDownloadTranslationAndRelatedFiles(translation: translation, files: files) .eraseToAnyPublisher() @@ -346,7 +346,13 @@ extension TranslationsRepository { }) .catch({ (error: Error) in - return self.downloadAndCacheTranslationZipFiles(translation: translation) + if !error.isUrlErrorNotConnectedToInternetCode { + return self.downloadAndCacheTranslationZipFiles(translation: translation) + } + else { + return Fail(error: error) + .eraseToAnyPublisher() + } }) .eraseToAnyPublisher() } @@ -359,7 +365,7 @@ extension TranslationsRepository { return self.getTranslationFileFromRemote(translation: translation, fileName: fileName) .eraseToAnyPublisher() }) - .flatMap({ fileCacheLocation -> AnyPublisher in + .flatMap({ (fileCacheLocation: FileCacheLocation) -> AnyPublisher in return Just(fileCacheLocation).setFailureType(to: Error.self) .eraseToAnyPublisher() diff --git a/godtools/Base.lproj/Localizable.strings b/godtools/Base.lproj/Localizable.strings index 536fc00866..6f2e9d27a3 100644 --- a/godtools/Base.lproj/Localizable.strings +++ b/godtools/Base.lproj/Localizable.strings @@ -1,3 +1,4 @@ +"network_connection_lost" = "The network connection was lost."; "language_name_fil" = "Filipino (Tagalog)"; "lessons.filter.navBar.language" = "Lesson language"; "lessons.languageFilter.title" = "Lessons in:"; @@ -297,7 +298,6 @@ An online version can be found at https://knowgod.com/"; "download_error" = "Download Error"; "no_internet_title" = "No internet connection"; "no_internet" = "Please check your internet connection and try again."; -"network_connection_lost" = "The network connection was lost."; "the_tool_you_requested_is_loading" = "The tool you requested is loading..."; "loading" = "Loading..."; diff --git a/godtools/am.lproj/Localizable.strings b/godtools/am.lproj/Localizable.strings index 26027c34ef..0536ab8c4f 100755 --- a/godtools/am.lproj/Localizable.strings +++ b/godtools/am.lproj/Localizable.strings @@ -1,3 +1,4 @@ +"network_connection_lost" = "ኢንተርኔቱ ለጊዜው ተቋርጧል"; "language_name_fil" = "ፊሊፒኖ (ታጋሎግ)"; "lessons.filter.navBar.language" = "የትምህርቱ ቋንቋ"; "lessons.languageFilter.title" = "ትምህርቶች በ"; diff --git a/godtools/ar.lproj/Localizable.strings b/godtools/ar.lproj/Localizable.strings index 6c2effde43..3faca49657 100755 --- a/godtools/ar.lproj/Localizable.strings +++ b/godtools/ar.lproj/Localizable.strings @@ -1,3 +1,4 @@ +"network_connection_lost" = "تم فقدان الاتصال بالشبكة."; "language_name_fil" = "الفلبينية (تاجالوج)"; "lessons.filter.navBar.language" = "لُغة الدرس"; "lessons.languageFilter.title" = "دروس في:"; diff --git a/godtools/de.lproj/Localizable.strings b/godtools/de.lproj/Localizable.strings index eba9fd74c5..d5f37b18e1 100755 --- a/godtools/de.lproj/Localizable.strings +++ b/godtools/de.lproj/Localizable.strings @@ -1,3 +1,4 @@ +"network_connection_lost" = "Die Netzwerkverbindung wurde unterbrochen."; "language_name_fil" = "Philippinisch (Tagalog)"; "lessons.filter.navBar.language" = "Lektionssprache"; "lessons.languageFilter.title" = "Lektionen in:"; diff --git a/godtools/es.lproj/Localizable.strings b/godtools/es.lproj/Localizable.strings index 2cafe18181..2abae4344b 100755 --- a/godtools/es.lproj/Localizable.strings +++ b/godtools/es.lproj/Localizable.strings @@ -1,3 +1,4 @@ +"network_connection_lost" = "Se perdió la conexión de red."; "language_name_fil" = "Filipino (Tagalog)"; "lessons.filter.navBar.language" = "Idioma de la lección"; "lessons.languageFilter.title" = "Lecciones en:"; diff --git a/godtools/fr.lproj/Localizable.strings b/godtools/fr.lproj/Localizable.strings index 0a850da6e1..e908c50161 100755 --- a/godtools/fr.lproj/Localizable.strings +++ b/godtools/fr.lproj/Localizable.strings @@ -1,3 +1,4 @@ +"network_connection_lost" = "La connexion réseau a été perdue."; "language_name_fil" = "Philippine (Tagalog)"; "lessons.filter.navBar.language" = "Langue de la leçon"; "lessons.languageFilter.title" = "Leçons en :"; diff --git a/godtools/hi.lproj/Localizable.strings b/godtools/hi.lproj/Localizable.strings index 27dce36e9f..5e8b0ea9a8 100755 --- a/godtools/hi.lproj/Localizable.strings +++ b/godtools/hi.lproj/Localizable.strings @@ -1,3 +1,4 @@ +"network_connection_lost" = "नेटवर्क कनेक्शन खो गया।"; "language_name_fil" = "फिलिपीनी"; "lessons.filter.navBar.language" = "पाठ की भाषा"; "lessons.languageFilter.title" = "इसमें पाठ:"; diff --git a/godtools/id.lproj/Localizable.strings b/godtools/id.lproj/Localizable.strings index 479190ddaa..4f5044b9ef 100755 --- a/godtools/id.lproj/Localizable.strings +++ b/godtools/id.lproj/Localizable.strings @@ -1,3 +1,4 @@ +"network_connection_lost" = "Koneksi jaringan terputus."; "language_name_fil" = "Filipina (Tagalog)"; "lessons.filter.navBar.language" = "Bahasa pelajaran"; "lessons.languageFilter.title" = "Pelajaran dalam bahasa:"; diff --git a/godtools/ja.lproj/Localizable.strings b/godtools/ja.lproj/Localizable.strings index dcc1a5d1fb..f07b6c59ea 100755 --- a/godtools/ja.lproj/Localizable.strings +++ b/godtools/ja.lproj/Localizable.strings @@ -1,3 +1,4 @@ +"network_connection_lost" = "ネットワーク接続が失われました。"; "language_name_fil" = "フィリピン(タガログ)語"; "lessons.filter.navBar.language" = "レッスン言語"; "lessons.languageFilter.title" = "レッスン:"; diff --git a/godtools/ko.lproj/Localizable.strings b/godtools/ko.lproj/Localizable.strings index 5ca88dfd5c..42aca406c2 100644 --- a/godtools/ko.lproj/Localizable.strings +++ b/godtools/ko.lproj/Localizable.strings @@ -1,3 +1,4 @@ +"network_connection_lost" = "네트워크 연결이 끊어졌습니다."; "language_name_fil" = "필리핀어(타갈로그)"; "lessons.filter.navBar.language" = "수업 언어"; "lessons.languageFilter.title" = "수업 언어:"; diff --git a/godtools/lv-LV.lproj/Localizable.strings b/godtools/lv-LV.lproj/Localizable.strings index 9063103208..ed556c2d7f 100755 --- a/godtools/lv-LV.lproj/Localizable.strings +++ b/godtools/lv-LV.lproj/Localizable.strings @@ -1,3 +1,4 @@ +"network_connection_lost" = "Tīkla savienojums tika pārtraukts."; "language_name_fil" = "filipīniešu (tagalu)"; "lessons.filter.navBar.language" = "Nodarbības valoda"; "lessons.languageFilter.title" = "Nodarbības"; diff --git a/godtools/lv.lproj/Localizable.strings b/godtools/lv.lproj/Localizable.strings index 9063103208..ed556c2d7f 100644 --- a/godtools/lv.lproj/Localizable.strings +++ b/godtools/lv.lproj/Localizable.strings @@ -1,3 +1,4 @@ +"network_connection_lost" = "Tīkla savienojums tika pārtraukts."; "language_name_fil" = "filipīniešu (tagalu)"; "lessons.filter.navBar.language" = "Nodarbības valoda"; "lessons.languageFilter.title" = "Nodarbības"; diff --git a/godtools/pt.lproj/Localizable.strings b/godtools/pt.lproj/Localizable.strings index a421e7441c..34fe8e142a 100755 --- a/godtools/pt.lproj/Localizable.strings +++ b/godtools/pt.lproj/Localizable.strings @@ -1,3 +1,4 @@ +"network_connection_lost" = "A conexão de rede foi perdida."; "language_name_fil" = "Filipino (Tagalog)"; "lessons.filter.navBar.language" = "Idioma da lição"; "lessons.languageFilter.title" = "Lições em:"; diff --git a/godtools/ru.lproj/Localizable.strings b/godtools/ru.lproj/Localizable.strings index 508ccbf76c..71d58971c0 100755 --- a/godtools/ru.lproj/Localizable.strings +++ b/godtools/ru.lproj/Localizable.strings @@ -1,3 +1,4 @@ +"network_connection_lost" = "Соединение с сетью потеряно."; "language_name_fil" = "Филиппинский (Тагальский)"; "lessons.filter.navBar.language" = "Язык урока"; "lessons.languageFilter.title" = "Язык уроков:"; diff --git a/godtools/sw.lproj/Localizable.strings b/godtools/sw.lproj/Localizable.strings index 87d834ef9b..65d9ac821e 100755 --- a/godtools/sw.lproj/Localizable.strings +++ b/godtools/sw.lproj/Localizable.strings @@ -1,3 +1,4 @@ +"network_connection_lost" = "Mtandao umepotea."; "language_name_fil" = "Kifilipino (Kitagalog)"; "lessons.filter.navBar.language" = "Lugha ya somo"; "lessons.languageFilter.title" = "Masomo yaliyopo:"; diff --git a/godtools/ur.lproj/Localizable.strings b/godtools/ur.lproj/Localizable.strings index dc774b6262..87e5e231c4 100755 --- a/godtools/ur.lproj/Localizable.strings +++ b/godtools/ur.lproj/Localizable.strings @@ -1,3 +1,4 @@ +"network_connection_lost" = "نیٹ ورک کنکشن ختم ہوگیا۔"; "language_name_fil" = "فلپائینی(تاگالوگ)"; "lessons.filter.navBar.language" = "سبق کی زبان"; "lessons.languageFilter.title" = "اسباق در:"; diff --git a/godtools/vi.lproj/Localizable.strings b/godtools/vi.lproj/Localizable.strings index 311ecab1a9..e9dac58224 100755 --- a/godtools/vi.lproj/Localizable.strings +++ b/godtools/vi.lproj/Localizable.strings @@ -1,3 +1,4 @@ +"network_connection_lost" = "Kết nối mạng đã bị mất."; "language_name_fil" = "Tiếng Philippines (Tagalog)"; "lessons.filter.navBar.language" = "Ngôn ngữ bài học"; "lessons.languageFilter.title" = "Bài học bằng:"; diff --git a/godtools/zh-Hans.lproj/Localizable.strings b/godtools/zh-Hans.lproj/Localizable.strings index 5b63e3d859..b4689c027a 100755 --- a/godtools/zh-Hans.lproj/Localizable.strings +++ b/godtools/zh-Hans.lproj/Localizable.strings @@ -1,3 +1,4 @@ +"network_connection_lost" = "网络连接已断开。"; "language_name_fil" = "菲律宾语(他加禄语)"; "lessons.filter.navBar.language" = "课程语言"; "lessons.languageFilter.title" = "课程所用语言:"; diff --git a/godtools/zh-Hant.lproj/Localizable.strings b/godtools/zh-Hant.lproj/Localizable.strings index af2cc56637..9802308aff 100755 --- a/godtools/zh-Hant.lproj/Localizable.strings +++ b/godtools/zh-Hant.lproj/Localizable.strings @@ -1,3 +1,4 @@ +"network_connection_lost" = "網絡連接已丟失。"; "language_name_fil" = "菲律賓文 (他加祿語)"; "lessons.filter.navBar.language" = "課程語言"; "lessons.languageFilter.title" = "課程語言:";