From 8c50ce3653e0681534b33bba09459a916425f121 Mon Sep 17 00:00:00 2001 From: Javier Cicchelli Date: Wed, 12 Apr 2023 15:22:30 +0200 Subject: [PATCH] Implemented the LoadRemoteLocationsUseCase use case. --- .../LoadRemoteLocationsUseCase.swift | 75 +++++++++++++++++++ DeepLinking.xcodeproj/project.pbxproj | 12 +++ 2 files changed, 87 insertions(+) create mode 100644 Apps/Locations/Sources/Use Cases/LoadRemoteLocationsUseCase.swift diff --git a/Apps/Locations/Sources/Use Cases/LoadRemoteLocationsUseCase.swift b/Apps/Locations/Sources/Use Cases/LoadRemoteLocationsUseCase.swift new file mode 100644 index 0000000..e64bd01 --- /dev/null +++ b/Apps/Locations/Sources/Use Cases/LoadRemoteLocationsUseCase.swift @@ -0,0 +1,75 @@ +// +// LoadRemoteLocationsUseCase.swift +// Locations +// +// Created by Javier Cicchelli on 12/04/2023. +// Copyright © 2023 Röck+Cöde. All rights reserved. +// + +import CoreData +import Dependency +import Persistence +import Remote + +struct LoadRemoteLocationsUseCase { + + // MARK: Properties + + private let persistence: PersistenceService + private let remoteService: RemoteService + + // MARK: Initialisers + + init( + persistence: PersistenceService, + remoteService: RemoteService + ) { + self.persistence = persistence + self.remoteService = remoteService + } + + func callAsFunction() async throws { + let context = persistence.makeTaskContext() + let fetchRequest = NSFetchRequest.allLocations() + + try await context.perform { + let localLocations = try context.fetch(fetchRequest) + + localLocations + .filter { $0.source == .remote } + .forEach(context.delete) + } + + let remoteLocations = try await remoteService.getLocations() + + _ = remoteLocations + .map { + let entity = Persistence.Location(context: context) + + entity.createdAt = .now + entity.name = $0.name + entity.latitude = $0.latitude + entity.longitude = $0.longitude + entity.source = .remote + + return entity + } + + persistence.save(context: context) + } + +} + +// MARK: - LoadRemoteLocationsUseCase+Initialisers + +extension LoadRemoteLocationsUseCase { + init() { + @Dependency(\.persistence) var persistence + @Dependency(\.remote) var remote + + self.init( + persistence: persistence, + remoteService: remote + ) + } +} diff --git a/DeepLinking.xcodeproj/project.pbxproj b/DeepLinking.xcodeproj/project.pbxproj index f83395d..f6a330a 100644 --- a/DeepLinking.xcodeproj/project.pbxproj +++ b/DeepLinking.xcodeproj/project.pbxproj @@ -12,6 +12,7 @@ 02031EC929E60B29003C108C /* DependencyService+Keys.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02031EC829E60B29003C108C /* DependencyService+Keys.swift */; }; 02031EE829E68D9B003C108C /* LoadingSpinnerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02031EE729E68D9B003C108C /* LoadingSpinnerView.swift */; }; 02031EEA29E6B495003C108C /* ErrorMessageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 02031EE929E6B495003C108C /* ErrorMessageView.swift */; }; + 4656CBC229E6D33C00600EE6 /* LoadRemoteLocationsUseCase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4656CBC129E6D33C00600EE6 /* LoadRemoteLocationsUseCase.swift */; }; 46C3B7C629E5BF1500F8F57C /* LocationsListCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46C3B7C529E5BF1500F8F57C /* LocationsListCoordinator.swift */; }; 46C3B7CB29E5CD3200F8F57C /* LocationsListViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46C3B7CA29E5CD3200F8F57C /* LocationsListViewModel.swift */; }; 46C3B7CF29E5D00E00F8F57C /* LocationsAddViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 46C3B7CE29E5D00E00F8F57C /* LocationsAddViewModel.swift */; }; @@ -128,6 +129,7 @@ 02031EC829E60B29003C108C /* DependencyService+Keys.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "DependencyService+Keys.swift"; sourceTree = ""; }; 02031EE729E68D9B003C108C /* LoadingSpinnerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadingSpinnerView.swift; sourceTree = ""; }; 02031EE929E6B495003C108C /* ErrorMessageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorMessageView.swift; sourceTree = ""; }; + 4656CBC129E6D33C00600EE6 /* LoadRemoteLocationsUseCase.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadRemoteLocationsUseCase.swift; sourceTree = ""; }; 46C3B7C529E5BF1500F8F57C /* LocationsListCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationsListCoordinator.swift; sourceTree = ""; }; 46C3B7CA29E5CD3200F8F57C /* LocationsListViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationsListViewModel.swift; sourceTree = ""; }; 46C3B7CE29E5D00E00F8F57C /* LocationsAddViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocationsAddViewModel.swift; sourceTree = ""; }; @@ -214,6 +216,14 @@ path = Coordination; sourceTree = ""; }; + 4656CBC029E6D31800600EE6 /* Use Cases */ = { + isa = PBXGroup; + children = ( + 4656CBC129E6D33C00600EE6 /* LoadRemoteLocationsUseCase.swift */, + ); + path = "Use Cases"; + sourceTree = ""; + }; 46C3B7C429E5BEE900F8F57C /* Coordinators */ = { isa = PBXGroup; children = ( @@ -318,6 +328,7 @@ 46C3B7C929E5CB8F00F8F57C /* Screens */, 02031EC429E5FEB1003C108C /* View Controllers */, 02031EE629E68D7A003C108C /* View Components */, + 4656CBC029E6D31800600EE6 /* Use Cases */, ); path = Sources; sourceTree = ""; @@ -533,6 +544,7 @@ 46C3B7DC29E5ED2300F8F57C /* LocationsAddCoordination.swift in Sources */, 46C3B7D829E5E55000F8F57C /* LocationsListCoordination.swift in Sources */, 46C3B7D629E5E50500F8F57C /* LocationsListViewModeling.swift in Sources */, + 4656CBC229E6D33C00600EE6 /* LoadRemoteLocationsUseCase.swift in Sources */, 46C3B7CF29E5D00E00F8F57C /* LocationsAddViewModel.swift in Sources */, 02031EC929E60B29003C108C /* DependencyService+Keys.swift in Sources */, 46C3B7D129E5D06D00F8F57C /* LocationsAddViewController.swift in Sources */,