From 38d8951deafc8833757cec2d84ebf1ab75c8e487 Mon Sep 17 00:00:00 2001 From: summjai Date: Tue, 3 Mar 2020 23:14:27 +0300 Subject: [PATCH] add async save --- .../Service/StockSymbolStorgeService.swift | 8 ++++-- .../StockList/StockListPresenter.swift | 7 +++--- DevPods/Storage/Podfile.lock | 4 +-- .../Storage/Storage.xcodeproj/project.pbxproj | 22 +++++++++------- .../contents.xcworkspacedata | 10 ++++++++ .../xcshareddata/IDEWorkspaceChecks.plist | 8 ++++++ DevPods/Storage/Storage/StorageService.swift | 25 +++++++++++-------- 7 files changed, 58 insertions(+), 26 deletions(-) create mode 100644 DevPods/Storage/Storage.xcworkspace/contents.xcworkspacedata create mode 100644 DevPods/Storage/Storage.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist diff --git a/DevPods/StockList/StockList/Services/Service/StockSymbolStorgeService.swift b/DevPods/StockList/StockList/Services/Service/StockSymbolStorgeService.swift index 5c0b547..e79c254 100644 --- a/DevPods/StockList/StockList/Services/Service/StockSymbolStorgeService.swift +++ b/DevPods/StockList/StockList/Services/Service/StockSymbolStorgeService.swift @@ -17,13 +17,17 @@ final class StockSymbolStorgeService { )! ) - func persist(stockSymbols: [StockSymbol]) { + func persist( + stockSymbols: [StockSymbol], + completion: @escaping () -> Void + ) { stockSymbols.forEach { symbol in storageService.persist( updateWith: { (dbSymbol: DBStockSymbol) in dbSymbol.updateWithDomainModel(symbol) }, - predicate: NSPredicate(format: "symbol = %@", "\(symbol.symbol)") + predicate: NSPredicate(format: "symbol = %@", "\(symbol.symbol)"), + completion: completion ) } } diff --git a/DevPods/StockList/StockList/StockListPresenter.swift b/DevPods/StockList/StockList/StockListPresenter.swift index 8d2b2dd..682e9c1 100644 --- a/DevPods/StockList/StockList/StockListPresenter.swift +++ b/DevPods/StockList/StockList/StockListPresenter.swift @@ -72,9 +72,10 @@ extension StockListPresenter { ) { switch $0 { case .success(let stocks): - self.storageService.persist(stockSymbols: stocks) - self.stocks = stocks - self.view?.showTable(with: stocks.map(StockDisplayModel.init)) + self.storageService.persist(stockSymbols: stocks) { + self.stocks = stocks + self.view?.showTable(with: stocks.map(StockDisplayModel.init)) + } case .failure: self.view?.showError() } diff --git a/DevPods/Storage/Podfile.lock b/DevPods/Storage/Podfile.lock index 111ec46..22ad6f8 100644 --- a/DevPods/Storage/Podfile.lock +++ b/DevPods/Storage/Podfile.lock @@ -1,3 +1,3 @@ -PODFILE CHECKSUM: 5259f5868453460955f33295d8d76460bade8cee +PODFILE CHECKSUM: 28a690778519c7cfb0688c8b2f0df675c0cf0abe -COCOAPODS: 1.8.4 +COCOAPODS: 1.9.0 diff --git a/DevPods/Storage/Storage.xcodeproj/project.pbxproj b/DevPods/Storage/Storage.xcodeproj/project.pbxproj index bc3d060..592a27d 100644 --- a/DevPods/Storage/Storage.xcodeproj/project.pbxproj +++ b/DevPods/Storage/Storage.xcodeproj/project.pbxproj @@ -7,19 +7,21 @@ objects = { /* Begin PBXBuildFile section */ + 3D7FC6FA6B39EFA82189AE56 /* Pods_Storage.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96E5B5075D9B764A83369F32 /* Pods_Storage.framework */; }; D9BE6F94240BFA8A005D9A3D /* StorageService.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9BE6F93240BFA8A005D9A3D /* StorageService.swift */; }; D9BE6F96240BFB28005D9A3D /* DBInsertable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D9BE6F95240BFB28005D9A3D /* DBInsertable.swift */; }; - EA64D4B3A220B7CF00125FFF /* Pods_Container.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E9C71DF0779063A1FE3F1F38 /* Pods_Container.framework */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ 21647414F3C4263CA586C215 /* Pods-Container.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Container.debug.xcconfig"; path = "Target Support Files/Pods-Container/Pods-Container.debug.xcconfig"; sourceTree = ""; }; + 4405B5D406F7C81598FDCA90 /* Pods-Storage.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Storage.debug.xcconfig"; path = "Target Support Files/Pods-Storage/Pods-Storage.debug.xcconfig"; sourceTree = ""; }; 86F52DFEDC248438C25D6756 /* Pods-Container.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Container.release.xcconfig"; path = "Target Support Files/Pods-Container/Pods-Container.release.xcconfig"; sourceTree = ""; }; + 96E5B5075D9B764A83369F32 /* Pods_Storage.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Storage.framework; sourceTree = BUILT_PRODUCTS_DIR; }; D9BE6F88240BED33005D9A3D /* Storage.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Storage.framework; sourceTree = BUILT_PRODUCTS_DIR; }; D9BE6F8C240BED33005D9A3D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; D9BE6F93240BFA8A005D9A3D /* StorageService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StorageService.swift; sourceTree = ""; }; D9BE6F95240BFB28005D9A3D /* DBInsertable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DBInsertable.swift; sourceTree = ""; }; - E9C71DF0779063A1FE3F1F38 /* Pods_Container.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Container.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + E63F0C955B35A82BDF62ECC4 /* Pods-Storage.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Storage.release.xcconfig"; path = "Target Support Files/Pods-Storage/Pods-Storage.release.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -27,7 +29,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - EA64D4B3A220B7CF00125FFF /* Pods_Container.framework in Frameworks */, + 3D7FC6FA6B39EFA82189AE56 /* Pods_Storage.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -37,7 +39,7 @@ 1B77DDF426405A68DA4E8AA3 /* Frameworks */ = { isa = PBXGroup; children = ( - E9C71DF0779063A1FE3F1F38 /* Pods_Container.framework */, + 96E5B5075D9B764A83369F32 /* Pods_Storage.framework */, ); name = Frameworks; sourceTree = ""; @@ -47,6 +49,8 @@ children = ( 21647414F3C4263CA586C215 /* Pods-Container.debug.xcconfig */, 86F52DFEDC248438C25D6756 /* Pods-Container.release.xcconfig */, + 4405B5D406F7C81598FDCA90 /* Pods-Storage.debug.xcconfig */, + E63F0C955B35A82BDF62ECC4 /* Pods-Storage.release.xcconfig */, ); path = Pods; sourceTree = ""; @@ -170,7 +174,7 @@ outputFileListPaths = ( ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-Container-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-Storage-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -314,7 +318,7 @@ }; D9BE6F91240BED33005D9A3D /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 21647414F3C4263CA586C215 /* Pods-Container.debug.xcconfig */; + baseConfigurationReference = 4405B5D406F7C81598FDCA90 /* Pods-Storage.debug.xcconfig */; buildSettings = { CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; @@ -322,7 +326,7 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = Container/Info.plist; + INFOPLIST_FILE = Storage/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -340,7 +344,7 @@ }; D9BE6F92240BED33005D9A3D /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 86F52DFEDC248438C25D6756 /* Pods-Container.release.xcconfig */; + baseConfigurationReference = E63F0C955B35A82BDF62ECC4 /* Pods-Storage.release.xcconfig */; buildSettings = { CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; @@ -348,7 +352,7 @@ DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; DYLIB_INSTALL_NAME_BASE = "@rpath"; - INFOPLIST_FILE = Container/Info.plist; + INFOPLIST_FILE = Storage/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", diff --git a/DevPods/Storage/Storage.xcworkspace/contents.xcworkspacedata b/DevPods/Storage/Storage.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..d52b182 --- /dev/null +++ b/DevPods/Storage/Storage.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/DevPods/Storage/Storage.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/DevPods/Storage/Storage.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/DevPods/Storage/Storage.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/DevPods/Storage/Storage/StorageService.swift b/DevPods/Storage/Storage/StorageService.swift index c2345da..f1883c2 100644 --- a/DevPods/Storage/Storage/StorageService.swift +++ b/DevPods/Storage/Storage/StorageService.swift @@ -31,9 +31,10 @@ public final class StorageService { return container }() - public var viewContext: NSManagedObjectContext { + private var viewContext: NSManagedObjectContext { container.viewContext } + private lazy var backgroundContext = container.newBackgroundContext() public func fetch(predicate: NSPredicate?) -> [T]? { var objects: [T]? @@ -48,20 +49,24 @@ public final class StorageService { } public func persist( - updateWith: (T) -> Void, - predicate: NSPredicate + updateWith: @escaping (T) -> Void, + predicate: NSPredicate, + completion: @escaping () -> Void ) { - viewContext.performAndWait { + backgroundContext.perform { T.insertOrUpdate( - context: viewContext, + context: self.viewContext, updateWith: updateWith, predicate: predicate ) - } - do { - try viewContext.save() - } catch { - viewContext.rollback() + do { + try self.viewContext.save() + } catch { + self.viewContext.rollback() + } + DispatchQueue.main.async { + completion() + } } } }