diff --git a/Cloudinary.xcodeproj/project.pbxproj b/Cloudinary.xcodeproj/project.pbxproj index c8a57e96..f2802ec8 100644 --- a/Cloudinary.xcodeproj/project.pbxproj +++ b/Cloudinary.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + B690BF5E2BC55992007117AC /* HTTPStatusCode.swift in Sources */ = {isa = PBXBuildFile; fileRef = B690BF5D2BC55992007117AC /* HTTPStatusCode.swift */; }; B694AAEC2B308AF100075041 /* CLDAnalytics.swift in Sources */ = {isa = PBXBuildFile; fileRef = B694AAEB2B308AF100075041 /* CLDAnalytics.swift */; }; B694AAEF2B308B8400075041 /* VideoAnalytics.swift in Sources */ = {isa = PBXBuildFile; fileRef = B694AAEE2B308B8400075041 /* VideoAnalytics.swift */; }; B694AAF12B308B9D00075041 /* VideoEventsManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B694AAF02B308B9D00075041 /* VideoEventsManager.swift */; }; @@ -30,34 +31,6 @@ OBJ_273 /* CLDConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_26 /* CLDConfiguration.swift */; }; OBJ_274 /* CLDEagerTransformation.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_27 /* CLDEagerTransformation.swift */; }; OBJ_275 /* CLDResponsiveParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_28 /* CLDResponsiveParams.swift */; }; - OBJ_276 /* CLDURLCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_32 /* CLDURLCache.swift */; }; - OBJ_277 /* CLDURLCacheConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_33 /* CLDURLCacheConfiguration.swift */; }; - OBJ_278 /* HTTPStatusCode.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_35 /* HTTPStatusCode.swift */; }; - OBJ_279 /* ExtensionDateFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_37 /* ExtensionDateFormatter.swift */; }; - OBJ_280 /* ExtensionHTTPURLResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_38 /* ExtensionHTTPURLResponse.swift */; }; - OBJ_281 /* ExtensionURL.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_39 /* ExtensionURL.swift */; }; - OBJ_282 /* ExtensionURLRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_40 /* ExtensionURLRequest.swift */; }; - OBJ_283 /* ExtensionURLRequestCachePolicy.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_41 /* ExtensionURLRequestCachePolicy.swift */; }; - OBJ_284 /* StorehouseAccessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_45 /* StorehouseAccessor.swift */; }; - OBJ_285 /* StorehouseAny.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_47 /* StorehouseAny.swift */; }; - OBJ_286 /* StorehouseAnyFileSystem.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_48 /* StorehouseAnyFileSystem.swift */; }; - OBJ_287 /* StorehouseAnyInMemory.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_49 /* StorehouseAnyInMemory.swift */; }; - OBJ_288 /* StorehouseConfigurationAutoPurging.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_51 /* StorehouseConfigurationAutoPurging.swift */; }; - OBJ_289 /* StorehouseConfigurationDisk.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_52 /* StorehouseConfigurationDisk.swift */; }; - OBJ_290 /* StorehouseConfigurationInMemory.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_53 /* StorehouseConfigurationInMemory.swift */; }; - OBJ_291 /* StorehouseEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_55 /* StorehouseEntry.swift */; }; - OBJ_292 /* StorehouseExpiry.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_56 /* StorehouseExpiry.swift */; }; - OBJ_293 /* StorehouseTransformer.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_57 /* StorehouseTransformer.swift */; }; - OBJ_294 /* StorehouseHybrid.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_59 /* StorehouseHybrid.swift */; }; - OBJ_295 /* StorehouseProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_60 /* StorehouseProtocol.swift */; }; - OBJ_296 /* StorehouseAutoPurging.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_62 /* StorehouseAutoPurging.swift */; }; - OBJ_297 /* StorehouseInMemory.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_63 /* StorehouseInMemory.swift */; }; - OBJ_298 /* StorehouseOnDisk.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_64 /* StorehouseOnDisk.swift */; }; - OBJ_299 /* Warehouse.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_65 /* Warehouse.swift */; }; - OBJ_300 /* WarehouseTransformerFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_66 /* WarehouseTransformerFactory.swift */; }; - OBJ_301 /* StorehouseError.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_68 /* StorehouseError.swift */; }; - OBJ_302 /* ExtensionDate.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_70 /* ExtensionDate.swift */; }; - OBJ_303 /* ExtensionOptional.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_71 /* ExtensionOptional.swift */; }; OBJ_304 /* CLDDownloader.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_73 /* CLDDownloader.swift */; }; OBJ_305 /* CLDBaseNetworkObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_75 /* CLDBaseNetworkObject.swift */; }; OBJ_306 /* CLDConditionExpression.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_76 /* CLDConditionExpression.swift */; }; @@ -173,7 +146,6 @@ OBJ_416 /* CLDDictionaryUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_216 /* CLDDictionaryUtils.swift */; }; OBJ_417 /* CLDError.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_217 /* CLDError.swift */; }; OBJ_418 /* CLDFileUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_218 /* CLDFileUtils.swift */; }; - OBJ_419 /* CLDImageCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_219 /* CLDImageCache.swift */; }; OBJ_420 /* CLDImageGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_221 /* CLDImageGenerator.swift */; }; OBJ_421 /* CLDImageUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_222 /* CLDImageUtils.swift */; }; OBJ_422 /* CLDJsonUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = OBJ_223 /* CLDJsonUtils.swift */; }; @@ -194,6 +166,7 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + B690BF5D2BC55992007117AC /* HTTPStatusCode.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = HTTPStatusCode.swift; path = CacheSystem/Enum/HTTPStatusCode.swift; sourceTree = ""; }; B694AAEB2B308AF100075041 /* CLDAnalytics.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CLDAnalytics.swift; sourceTree = ""; }; B694AAEE2B308B8400075041 /* VideoAnalytics.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoAnalytics.swift; sourceTree = ""; }; B694AAF02B308B9D00075041 /* VideoEventsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VideoEventsManager.swift; sourceTree = ""; }; @@ -307,7 +280,6 @@ OBJ_216 /* CLDDictionaryUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CLDDictionaryUtils.swift; sourceTree = ""; }; OBJ_217 /* CLDError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CLDError.swift; sourceTree = ""; }; OBJ_218 /* CLDFileUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CLDFileUtils.swift; sourceTree = ""; }; - OBJ_219 /* CLDImageCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CLDImageCache.swift; sourceTree = ""; }; OBJ_22 /* CLDNValidation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CLDNValidation.swift; sourceTree = ""; }; OBJ_221 /* CLDImageGenerator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CLDImageGenerator.swift; sourceTree = ""; }; OBJ_222 /* CLDImageUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CLDImageUtils.swift; sourceTree = ""; }; @@ -338,35 +310,7 @@ OBJ_26 /* CLDConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CLDConfiguration.swift; sourceTree = ""; }; OBJ_27 /* CLDEagerTransformation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CLDEagerTransformation.swift; sourceTree = ""; }; OBJ_28 /* CLDResponsiveParams.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CLDResponsiveParams.swift; sourceTree = ""; }; - OBJ_32 /* CLDURLCache.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CLDURLCache.swift; sourceTree = ""; }; - OBJ_33 /* CLDURLCacheConfiguration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CLDURLCacheConfiguration.swift; sourceTree = ""; }; - OBJ_35 /* HTTPStatusCode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HTTPStatusCode.swift; sourceTree = ""; }; - OBJ_37 /* ExtensionDateFormatter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionDateFormatter.swift; sourceTree = ""; }; - OBJ_38 /* ExtensionHTTPURLResponse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionHTTPURLResponse.swift; sourceTree = ""; }; - OBJ_39 /* ExtensionURL.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionURL.swift; sourceTree = ""; }; - OBJ_40 /* ExtensionURLRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionURLRequest.swift; sourceTree = ""; }; - OBJ_41 /* ExtensionURLRequestCachePolicy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionURLRequestCachePolicy.swift; sourceTree = ""; }; - OBJ_45 /* StorehouseAccessor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StorehouseAccessor.swift; sourceTree = ""; }; - OBJ_47 /* StorehouseAny.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StorehouseAny.swift; sourceTree = ""; }; - OBJ_48 /* StorehouseAnyFileSystem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StorehouseAnyFileSystem.swift; sourceTree = ""; }; - OBJ_49 /* StorehouseAnyInMemory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StorehouseAnyInMemory.swift; sourceTree = ""; }; - OBJ_51 /* StorehouseConfigurationAutoPurging.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StorehouseConfigurationAutoPurging.swift; sourceTree = ""; }; - OBJ_52 /* StorehouseConfigurationDisk.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StorehouseConfigurationDisk.swift; sourceTree = ""; }; - OBJ_53 /* StorehouseConfigurationInMemory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StorehouseConfigurationInMemory.swift; sourceTree = ""; }; - OBJ_55 /* StorehouseEntry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StorehouseEntry.swift; sourceTree = ""; }; - OBJ_56 /* StorehouseExpiry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StorehouseExpiry.swift; sourceTree = ""; }; - OBJ_57 /* StorehouseTransformer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StorehouseTransformer.swift; sourceTree = ""; }; - OBJ_59 /* StorehouseHybrid.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StorehouseHybrid.swift; sourceTree = ""; }; OBJ_6 /* Package.swift */ = {isa = PBXFileReference; explicitFileType = sourcecode.swift; path = Package.swift; sourceTree = ""; }; - OBJ_60 /* StorehouseProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StorehouseProtocol.swift; sourceTree = ""; }; - OBJ_62 /* StorehouseAutoPurging.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StorehouseAutoPurging.swift; sourceTree = ""; }; - OBJ_63 /* StorehouseInMemory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StorehouseInMemory.swift; sourceTree = ""; }; - OBJ_64 /* StorehouseOnDisk.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StorehouseOnDisk.swift; sourceTree = ""; }; - OBJ_65 /* Warehouse.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Warehouse.swift; sourceTree = ""; }; - OBJ_66 /* WarehouseTransformerFactory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WarehouseTransformerFactory.swift; sourceTree = ""; }; - OBJ_68 /* StorehouseError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StorehouseError.swift; sourceTree = ""; }; - OBJ_70 /* ExtensionDate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionDate.swift; sourceTree = ""; }; - OBJ_71 /* ExtensionOptional.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionOptional.swift; sourceTree = ""; }; OBJ_73 /* CLDDownloader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CLDDownloader.swift; sourceTree = ""; }; OBJ_75 /* CLDBaseNetworkObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CLDBaseNetworkObject.swift; sourceTree = ""; }; OBJ_76 /* CLDConditionExpression.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CLDConditionExpression.swift; sourceTree = ""; }; @@ -680,7 +624,6 @@ OBJ_216 /* CLDDictionaryUtils.swift */, OBJ_217 /* CLDError.swift */, OBJ_218 /* CLDFileUtils.swift */, - OBJ_219 /* CLDImageCache.swift */, OBJ_220 /* CLDImageGenerator */, OBJ_222 /* CLDImageUtils.swift */, OBJ_223 /* CLDJsonUtils.swift */, @@ -767,7 +710,7 @@ OBJ_29 /* Features */ = { isa = PBXGroup; children = ( - OBJ_30 /* CacheSystem */, + B690BF5D2BC55992007117AC /* HTTPStatusCode.swift */, OBJ_72 /* Downloader */, OBJ_74 /* Helpers */, OBJ_121 /* ManagementApi */, @@ -778,90 +721,6 @@ path = Features; sourceTree = ""; }; - OBJ_30 /* CacheSystem */ = { - isa = PBXGroup; - children = ( - OBJ_31 /* Class */, - OBJ_34 /* Enum */, - OBJ_36 /* Extensions */, - OBJ_42 /* StorehouseLibrary */, - ); - path = CacheSystem; - sourceTree = ""; - }; - OBJ_31 /* Class */ = { - isa = PBXGroup; - children = ( - OBJ_32 /* CLDURLCache.swift */, - OBJ_33 /* CLDURLCacheConfiguration.swift */, - ); - path = Class; - sourceTree = ""; - }; - OBJ_34 /* Enum */ = { - isa = PBXGroup; - children = ( - OBJ_35 /* HTTPStatusCode.swift */, - ); - path = Enum; - sourceTree = ""; - }; - OBJ_36 /* Extensions */ = { - isa = PBXGroup; - children = ( - OBJ_37 /* ExtensionDateFormatter.swift */, - OBJ_38 /* ExtensionHTTPURLResponse.swift */, - OBJ_39 /* ExtensionURL.swift */, - OBJ_40 /* ExtensionURLRequest.swift */, - OBJ_41 /* ExtensionURLRequestCachePolicy.swift */, - ); - path = Extensions; - sourceTree = ""; - }; - OBJ_42 /* StorehouseLibrary */ = { - isa = PBXGroup; - children = ( - OBJ_43 /* Core */, - OBJ_67 /* Enum */, - OBJ_69 /* Extension */, - ); - path = StorehouseLibrary; - sourceTree = ""; - }; - OBJ_43 /* Core */ = { - isa = PBXGroup; - children = ( - OBJ_44 /* StorehouseAccess */, - OBJ_46 /* StorehouseAnyType */, - OBJ_50 /* StorehouseConfiguration */, - OBJ_54 /* StorehouseContent */, - OBJ_58 /* StorehouseHybrid */, - OBJ_60 /* StorehouseProtocol.swift */, - OBJ_61 /* StorehouseType */, - OBJ_65 /* Warehouse.swift */, - OBJ_66 /* WarehouseTransformerFactory.swift */, - ); - path = Core; - sourceTree = ""; - }; - OBJ_44 /* StorehouseAccess */ = { - isa = PBXGroup; - children = ( - OBJ_45 /* StorehouseAccessor.swift */, - ); - path = StorehouseAccess; - sourceTree = ""; - }; - OBJ_46 /* StorehouseAnyType */ = { - isa = PBXGroup; - children = ( - OBJ_47 /* StorehouseAny.swift */, - OBJ_48 /* StorehouseAnyFileSystem.swift */, - OBJ_49 /* StorehouseAnyInMemory.swift */, - ); - path = StorehouseAnyType; - sourceTree = ""; - }; OBJ_5 = { isa = PBXGroup; children = ( @@ -879,61 +738,6 @@ ); sourceTree = ""; }; - OBJ_50 /* StorehouseConfiguration */ = { - isa = PBXGroup; - children = ( - OBJ_51 /* StorehouseConfigurationAutoPurging.swift */, - OBJ_52 /* StorehouseConfigurationDisk.swift */, - OBJ_53 /* StorehouseConfigurationInMemory.swift */, - ); - path = StorehouseConfiguration; - sourceTree = ""; - }; - OBJ_54 /* StorehouseContent */ = { - isa = PBXGroup; - children = ( - OBJ_55 /* StorehouseEntry.swift */, - OBJ_56 /* StorehouseExpiry.swift */, - OBJ_57 /* StorehouseTransformer.swift */, - ); - path = StorehouseContent; - sourceTree = ""; - }; - OBJ_58 /* StorehouseHybrid */ = { - isa = PBXGroup; - children = ( - OBJ_59 /* StorehouseHybrid.swift */, - ); - path = StorehouseHybrid; - sourceTree = ""; - }; - OBJ_61 /* StorehouseType */ = { - isa = PBXGroup; - children = ( - OBJ_62 /* StorehouseAutoPurging.swift */, - OBJ_63 /* StorehouseInMemory.swift */, - OBJ_64 /* StorehouseOnDisk.swift */, - ); - path = StorehouseType; - sourceTree = ""; - }; - OBJ_67 /* Enum */ = { - isa = PBXGroup; - children = ( - OBJ_68 /* StorehouseError.swift */, - ); - path = Enum; - sourceTree = ""; - }; - OBJ_69 /* Extension */ = { - isa = PBXGroup; - children = ( - OBJ_70 /* ExtensionDate.swift */, - OBJ_71 /* ExtensionOptional.swift */, - ); - path = Extension; - sourceTree = ""; - }; OBJ_7 /* Sources */ = { isa = PBXGroup; children = ( @@ -1162,35 +966,7 @@ OBJ_273 /* CLDConfiguration.swift in Sources */, OBJ_274 /* CLDEagerTransformation.swift in Sources */, OBJ_275 /* CLDResponsiveParams.swift in Sources */, - OBJ_276 /* CLDURLCache.swift in Sources */, - OBJ_277 /* CLDURLCacheConfiguration.swift in Sources */, - OBJ_278 /* HTTPStatusCode.swift in Sources */, - OBJ_279 /* ExtensionDateFormatter.swift in Sources */, - OBJ_280 /* ExtensionHTTPURLResponse.swift in Sources */, - OBJ_281 /* ExtensionURL.swift in Sources */, - OBJ_282 /* ExtensionURLRequest.swift in Sources */, - OBJ_283 /* ExtensionURLRequestCachePolicy.swift in Sources */, - OBJ_284 /* StorehouseAccessor.swift in Sources */, - OBJ_285 /* StorehouseAny.swift in Sources */, - OBJ_286 /* StorehouseAnyFileSystem.swift in Sources */, - OBJ_287 /* StorehouseAnyInMemory.swift in Sources */, - OBJ_288 /* StorehouseConfigurationAutoPurging.swift in Sources */, - OBJ_289 /* StorehouseConfigurationDisk.swift in Sources */, - OBJ_290 /* StorehouseConfigurationInMemory.swift in Sources */, - OBJ_291 /* StorehouseEntry.swift in Sources */, - OBJ_292 /* StorehouseExpiry.swift in Sources */, - OBJ_293 /* StorehouseTransformer.swift in Sources */, - OBJ_294 /* StorehouseHybrid.swift in Sources */, - OBJ_295 /* StorehouseProtocol.swift in Sources */, - OBJ_296 /* StorehouseAutoPurging.swift in Sources */, - OBJ_297 /* StorehouseInMemory.swift in Sources */, - OBJ_298 /* StorehouseOnDisk.swift in Sources */, - OBJ_299 /* Warehouse.swift in Sources */, - OBJ_300 /* WarehouseTransformerFactory.swift in Sources */, - OBJ_301 /* StorehouseError.swift in Sources */, B694AAF12B308B9D00075041 /* VideoEventsManager.swift in Sources */, - OBJ_302 /* ExtensionDate.swift in Sources */, - OBJ_303 /* ExtensionOptional.swift in Sources */, OBJ_304 /* CLDDownloader.swift in Sources */, OBJ_305 /* CLDBaseNetworkObject.swift in Sources */, OBJ_306 /* CLDConditionExpression.swift in Sources */, @@ -1286,6 +1062,7 @@ OBJ_393 /* CLDVideoView.swift in Sources */, OBJ_394 /* CLDWidgetEditViewController.swift in Sources */, OBJ_395 /* CLDWidgetPreviewViewController.swift in Sources */, + B690BF5E2BC55992007117AC /* HTTPStatusCode.swift in Sources */, OBJ_396 /* CLDWidgetViewController.swift in Sources */, OBJ_397 /* CLDUploader.swift in Sources */, OBJ_398 /* CLDPreprocessChain.swift in Sources */, @@ -1309,7 +1086,6 @@ OBJ_416 /* CLDDictionaryUtils.swift in Sources */, OBJ_417 /* CLDError.swift in Sources */, OBJ_418 /* CLDFileUtils.swift in Sources */, - OBJ_419 /* CLDImageCache.swift in Sources */, OBJ_420 /* CLDImageGenerator.swift in Sources */, OBJ_421 /* CLDImageUtils.swift in Sources */, OBJ_422 /* CLDJsonUtils.swift in Sources */, diff --git a/Cloudinary/Classes/Core/CLDCloudinary.swift b/Cloudinary/Classes/Core/CLDCloudinary.swift index b329c7a9..87154254 100644 --- a/Cloudinary/Classes/Core/CLDCloudinary.swift +++ b/Cloudinary/Classes/Core/CLDCloudinary.swift @@ -64,28 +64,12 @@ public typealias CLDUploadCompletionHandler = (_ response: CLDUploadResult?, _ e // MARK: Image Cache - /** - Sets Cloudinary SDK's caching policy for images that are downloaded via the SDK's CLDDownloader. - The options are: **None**, **Memory** and **Disk**. default is Disk - */ - open var cachePolicy: CLDImageCachePolicy { - get { - return downloadCoordinator.imageCache.cachePolicy - } - set { - downloadCoordinator.imageCache.cachePolicy = newValue - } - } open var enableUrlCache: Bool { get { - return downloadCoordinator.imageCache.cachePolicy == .none + return CLDDownloadCoordinator.enableCache } set { - if newValue == true { - downloadCoordinator.imageCache.cachePolicy = .none // turn old cache off - downloadCoordinator.imageCache.maxDiskCapacity = 0 // purge the old cache - } - downloadCoordinator.urlCache.shouldIncludeImages(newValue) // turn on the new cache if true + CLDDownloadCoordinator.enableCache = newValue } } @@ -93,12 +77,12 @@ public typealias CLDUploadCompletionHandler = (_ response: CLDUploadResult?, _ e Sets Cloudinary SDK's image cache maximum disk capacity. default is 150 MB. */ - open var cacheMaxDiskCapacity: UInt64 { + open var cacheMaxDiskCapacity: Int { get { - return downloadCoordinator.imageCache.maxDiskCapacity + return CLDDownloadCoordinator.urlCache.diskCapacity } set { - downloadCoordinator.imageCache.maxDiskCapacity = newValue + CLDDownloadCoordinator.urlCache.diskCapacity = newValue } } @@ -108,48 +92,12 @@ public typealias CLDUploadCompletionHandler = (_ response: CLDUploadResult?, _ e */ open var cacheMaxMemoryTotalCost: Int { get { - return downloadCoordinator.imageCache.maxMemoryTotalCost - } - set { - downloadCoordinator.imageCache.maxMemoryTotalCost = newValue - } - } - - /** - Sets Cloudinary SDK's asset cache maximum disk capacity. - default is 150 MB. - */ - open var cacheAssetMaxDiskCapacity: Int { - get { - return downloadCoordinator.urlCache.diskCapacity - } - set { - downloadCoordinator.urlCache.updateDiskCapacity(newValue) - } - } - - /** - Sets Cloudinary SDK's asset cache maximum memory total cost. - default is 30 MB. - */ - open var cacheAssetMaxMemoryTotalCost: Int { - get { - return downloadCoordinator.urlCache.memoryCapacity + return CLDDownloadCoordinator.urlCache.memoryCapacity } set { - downloadCoordinator.urlCache.updateMemoryCapacity(newValue) + CLDDownloadCoordinator.urlCache.memoryCapacity = newValue } } - - /** - Removes an image from the downloaded images cache, both disk and memory. - - - parameter key: The full url of the image to remove. - - */ - open func removeFromCache(key: String) { - downloadCoordinator.imageCache.removeCacheImageForKey(key) - } // MARK: - Init diff --git a/Cloudinary/Classes/Core/Features/CacheSystem/Class/CLDURLCache.swift b/Cloudinary/Classes/Core/Features/CacheSystem/Class/CLDURLCache.swift deleted file mode 100644 index 83fa1225..00000000 --- a/Cloudinary/Classes/Core/Features/CacheSystem/Class/CLDURLCache.swift +++ /dev/null @@ -1,380 +0,0 @@ -// -// CLDURLCache.swift -// -// Copyright (c) 2021 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -import Foundation - -@objc(CLDURLCacheDelegate) -internal protocol CLDURLCacheDelegate : NSObjectProtocol { - @objc optional func networkAvailable(for urlCache: CLDURLCache) -> Bool - @objc optional func shouldExclude(response: HTTPURLResponse, for urlCache: CLDURLCache) -> Bool -} - -@objcMembers -@objc(CLDURLCache) -internal final class CLDURLCache : URLCache -{ - /// MARK: - Private properties - internal fileprivate(set) var warehouse : Warehouse! - internal fileprivate(set) var settings : CLDURLCacheConfiguration! - fileprivate var path : String? - internal weak var delegate : CLDURLCacheDelegate? - - internal var includeImages = false - - fileprivate var shouldReceateCacheResponse = false - - /// MARK: - Initializers - internal init(memoryCapacity: Int, diskCapacity: Int, diskPath path: String?, configuration settings: CLDURLCacheConfiguration = CLDURLCacheConfiguration.defualt) - { - self.settings = settings - self.path = path - - super.init(memoryCapacity: memoryCapacity, diskCapacity: diskCapacity, diskPath: path) - - handleWarehouse(memoryCapacity: memoryCapacity, diskCapacity: diskCapacity, diskPath: path, configuration: settings) - } - - internal override init(memoryCapacity: Int, diskCapacity: Int, diskPath path: String?) - { - fatalError("init(memoryCapacity:diskCapacity:diskPath) is not implemented, plase use: init(memoryCapacity:diskCapacity:diskPath:configuration: instead") - } - - /// MARK: - Properties Overrides - /// - /// - /// - internal override var memoryCapacity : Int { - get { return warehouse.memoryCapacity } - set { /* No-Op*/ } - } - internal override var diskCapacity : Int { - get { return warehouse.diskCapacity } - set { /* No-Op*/ } - } - - internal override var currentMemoryUsage : Int { - return warehouse.currentMemoryUsage - } - internal override var currentDiskUsage : Int { - return warehouse.currentDiskUsage - } - - /// MARK: - Method Overrides - /// - /// - /// - internal override func cachedResponse(for request: URLRequest) -> CachedURLResponse? - { - guard let urlObject = request.url else { - printLog(.debug, text: "CLDURLCache cannot extract CachedURLResponse for nil URLs") - return nil - } - let absoluteURLString = urlObject.absoluteString - - guard !absoluteURLString.isEmpty else { - printLog(.debug, text: "CLDURLCache cannot extract CachedURLResponse for empty URLs") - return nil - } - - //is caching allowed - guard request.cachePolicy != .reloadIgnoringLocalCacheData else { - printLog(.debug, text: "CLDURLCache cannot extract CachedURLResponse for this cache policy: \(request.cachePolicy)") - return nil - } - - var entry : StorehouseEntry? = nil - do { - entry = try warehouse.entry(forKey: absoluteURLString) - } - catch let error as NSError { - printLog(.debug, text: "CLDURLCache cannot read StorehouseEntry from storage. Error: \(error.debugDescription)") - } - - guard let responseEntry = entry else { return nil } - - // Check file status only if we have network, otherwise return it anyway. - if networkAvailable() && responseEntry.expiry.isExpired - { - let maxAge = request.value(forHTTPHeaderField: "Access-Control-Max-Age") ?? String(settings.maxCacheResponseAge) - printLog(.debug, text: "CLDURLCache cannot read item, older than \(maxAge) seconds") - } - - let response = responseEntry.object - - // I have to find out the difrence. For now I will let the developer checkt which version to use - if shouldReceateCacheResponse - { - if let HTTPURLResponse = response.response as? HTTPURLResponse, HTTPURLResponse.statusCode == 302 - { - if let redirectTo = HTTPURLResponse.allHeaderFields["Location"] as? String , let redirectURL = URL(string: redirectTo) { - - printLog(.debug, text: "Redirecting from: \(response.response.url?.absoluteString ?? "")\nto: \(redirectTo)") - - // returning the response of the redirected url - let redirectRequest = URLRequest(url: redirectURL, cachePolicy: request.cachePolicy, timeoutInterval: request.timeoutInterval) - return cachedResponse(for: redirectRequest) - } - } - guard let responseURL = response.response.url else { return response } - let URLResponse = Foundation.URLResponse(url: responseURL, mimeType: response.response.mimeType, expectedContentLength: response.data.count, textEncodingName: response.response.textEncodingName) - return CachedURLResponse(response: URLResponse, data: response.data, userInfo: response.userInfo, storagePolicy: .allowed) - } - return response - } - - /// - /// - /// - internal override func storeCachedResponse(_ cachedResponse: CachedURLResponse, for request: URLRequest) - { - let requestObject = request.cld_URLRequestWithoutFragment - - // When cache is ignored for read, it's a good idea not to store the result as well as this option - // have big chance to be used every times in the future for the same request. - // NOTE: This is a change regarding default URLCache behavior - switch requestObject.cachePolicy - { - case .reloadIgnoringLocalCacheData : return - case .reloadIgnoringLocalAndRemoteCacheData: return - default: break - } - - guard let httpResponse = cachedResponse.response as? HTTPURLResponse else { return } - guard let httpStatus = httpResponse.cld_code else { return } - - if !includeImages { - let shouldExclude = delegate?.shouldExclude?(response: httpResponse, for: self) - guard shouldExclude == false else { return } - } - - let expirationDate = httpResponse.cld_expirationDate(forCache: settings) - - switch cachedResponse.storagePolicy - { - case .allowed: fallthrough - case .allowedInMemoryOnly: - - guard cachedResponse.data.count < diskCapacity else { break } - - // RFC 2616 section 13.3.4 says clients MUST use Etag in any cache-conditional request if provided by server - guard let _ = httpResponse.cld_header.etag else { break } - guard let expirationDate = expirationDate else { - // This response is not cacheable, headers said - return - } - - guard expirationDate.timeIntervalSinceNow - settings.expirationDelayMinimum > 0 else { - // This response is not cacheable, headers said - return - } - - default: return - } - - if httpStatus.isClientError || httpStatus.isServerError - { - printLog(.debug, text: "CLDURLCache Do not cache error \(httpResponse.statusCode) page for : \(String(describing: requestObject.url)) \(httpResponse.debugDescription)") - return - } - - if let previousResponse = self.cachedResponse(for: requestObject) , previousResponse.data == cachedResponse.data { - return - } - - guard let urlObject = requestObject.url , let expiration = expirationDate else { return } - do { - try warehouse.setObject(cachedResponse, forKey: urlObject.absoluteString, expiry: .date(expiration)) - try warehouse.removeExpiredObjects() - } - catch let error as NSError { - printLog(.error, text: "Error \(error.debugDescription)") - } - } - - /// - /// - /// - internal override func removeCachedResponse(for request: URLRequest) - { - guard let urlObject = request.url else { return } - do { - try warehouse.removeObject(forKey: urlObject.absoluteString) - } - catch let error as NSError { - printLog(.error, text: "Error \(error.debugDescription)") - } - } - - /// - /// - /// - internal override func removeAllCachedResponses() - { - do { - try warehouse.removeAll() - } - catch let error as NSError { - printLog(.error, text: "Error \(error.debugDescription)") - } - } - - /// - /// - /// - internal override func removeCachedResponses(since date: Date) - { - do { - try warehouse.removeStoredObjects(since: date) - } - catch let error as NSError { - printLog(.error, text: "Error \(error.debugDescription)") - } - } - - /// - /// - /// - internal override func storeCachedResponse(_ cachedResponse: CachedURLResponse, for dataTask: URLSessionDataTask) - { - guard let urlRequest = dataTask.currentRequest else { return } - storeCachedResponse(cachedResponse, for: urlRequest) - } - - /// - /// - /// - internal override func getCachedResponse(for dataTask: URLSessionDataTask, completionHandler: @escaping (CachedURLResponse?) -> Void) - { - guard let urlRequest = dataTask.currentRequest else { completionHandler(nil); return } - let response = cachedResponse(for: urlRequest) - completionHandler( response ) - } - - /// - /// - /// - internal override func removeCachedResponse(for dataTask: URLSessionDataTask) - { - guard let urlRequest = dataTask.currentRequest else { return } - removeCachedResponse(for: urlRequest) - } - - /// - /// Clears the cache, by removing all CachedURLResponse objects that it stores older then the minCacheResponseAge. - /// - internal func clearCachedResponsesToMinAgeThreshold() - { - let current = Date() - let threshold = current.addingTimeInterval(-settings.minCacheResponseAge) - removeCachedResponses(since: threshold) - } - - /// - /// - /// - internal func updateDiskCapacity(_ newDiskCapacity: Int) { - handleWarehouse(memoryCapacity: memoryCapacity, diskCapacity: newDiskCapacity, diskPath: path, configuration: self.settings, onlyUpdate: true) - } - - /// - /// - /// - internal func updateMemoryCapacity(_ newMemoryCapacity: Int) { - handleWarehouse(memoryCapacity: newMemoryCapacity, diskCapacity: diskCapacity, diskPath: path, configuration: self.settings, onlyUpdate: true) - } - - /// - /// - /// - internal func updateMaxCacheResponseAge(_ newMaxResonseAge: TimeInterval) { - settings.maxCacheResponseAge = newMaxResonseAge - handleWarehouse(memoryCapacity: memoryCapacity, diskCapacity: diskCapacity, diskPath: path, configuration: self.settings, onlyUpdate: true) - } - - /// - /// - /// - internal func updateMinCacheResponseAge(_ newMinResonseAge: TimeInterval) { - settings.minCacheResponseAge = newMinResonseAge - handleWarehouse(memoryCapacity: memoryCapacity, diskCapacity: diskCapacity, diskPath: path, configuration: self.settings, onlyUpdate: true) - } - - /// - /// - /// - func shouldIncludeImages(_ includeImages: Bool) { - self.includeImages = includeImages - } -} - -// MARK: - private methods -extension CLDURLCache { - - /// - /// Create or update Warehouse object - /// - fileprivate func handleWarehouse(memoryCapacity: Int, diskCapacity: Int, diskPath path: String?, configuration settings: CLDURLCacheConfiguration = CLDURLCacheConfiguration.defualt, onlyUpdate: Bool = false) { - - let pathString : String - switch path { - case .none : pathString = String() - case .some(let path): pathString = path - } - - let maxTimeFrom1970 = Date(timeIntervalSinceNow: settings.maxCacheResponseAge).timeIntervalSince1970 - let expiry = StorehouseExpiry.secondsFrom1970(maxTimeFrom1970) - - let preferredCapacity = Int(floor(Double(memoryCapacity) * 0.7)) - - let purgingConfiguration = StorehouseConfigurationAutoPurging(expiry: expiry, - memory: memoryCapacity, - preferredMemoryUsageAfterPurge: preferredCapacity) - - let diskConfiguration = StorehouseConfigurationDisk(name: pathString, - expiry: expiry, - maxSize: diskCapacity, - protectionType: nil) - - let transformer : StorehouseTransformer - switch settings.securedStorage { - case true : transformer = WarehouseTransformerFactory.forSecuredCoding(ofType: CachedURLResponse.self) - case false: transformer = WarehouseTransformerFactory.forCoding (ofType: CachedURLResponse.self) - } - - if onlyUpdate { - try? self.warehouse.updateCacheCapacity(purgingConfig: purgingConfiguration, diskConfig: diskConfiguration, transformer: transformer) - } - else { - self.warehouse = try? Warehouse(purgingConfig: purgingConfiguration, diskConfig: diskConfiguration, transformer: transformer) - } - } - - /// - /// Check for network connectivity, assume connection if delegate not available - /// - fileprivate func networkAvailable() -> Bool - { - return delegate?.networkAvailable?(for: self) ?? true - } -} diff --git a/Cloudinary/Classes/Core/Features/CacheSystem/Class/CLDURLCacheConfiguration.swift b/Cloudinary/Classes/Core/Features/CacheSystem/Class/CLDURLCacheConfiguration.swift deleted file mode 100644 index 92986feb..00000000 --- a/Cloudinary/Classes/Core/Features/CacheSystem/Class/CLDURLCacheConfiguration.swift +++ /dev/null @@ -1,95 +0,0 @@ -// -// CLDURLCacheConfiguration.swift -// -// Copyright (c) 2020 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -import Foundation - -@objcMembers -@objc(CLDURLCacheConfiguration) -internal class CLDURLCacheConfiguration : NSObject { - - internal enum LogingScope { - case all - case debugOnly - case none - } - - /// - /// Used to mark if the cache should use secure disk storage or not - /// - /// Note: defualts to false - /// - internal var securedStorage : Bool - - /// - /// The default minimum age of a cached file in seconds. (3 days) - /// - internal var minCacheResponseAge : TimeInterval - - /// - /// The default maximum age of a cached file in seconds. (1 week) - /// - internal var maxCacheResponseAge : TimeInterval - - /// - /// Default cache expiration delay if none defined (1 hour) - /// - internal var expirationDelayDefault : TimeInterval - - /// - /// Minimum cache expiration delay toused if not specifieyid in the responce 5 minute - /// - internal var expirationDelayMinimum : TimeInterval - - /// - /// Default modification fraction is 10% since Last-Modified suggested by RFC2616 section 13.2.4 - /// - internal var lastModificationFraction : Double - - /// - /// Default loging scope is debug only - /// - internal var logingScope : LogingScope - - /// - /// - /// - internal class var defualt : CLDURLCacheConfiguration { - return CLDURLCacheConfiguration() - } - - /// - /// - /// - internal override init() - { - self.securedStorage = false - self.minCacheResponseAge = TimeInterval(259200) - self.maxCacheResponseAge = TimeInterval(604800) - self.expirationDelayDefault = TimeInterval(1 * 60 * 60) // 1 hours - self.expirationDelayMinimum = TimeInterval(5 * 60 ) // 5 minutes - self.lastModificationFraction = Double(0.1) - self.logingScope = .debugOnly - super.init() - } -} diff --git a/Cloudinary/Classes/Core/Features/CacheSystem/Extensions/ExtensionDateFormatter.swift b/Cloudinary/Classes/Core/Features/CacheSystem/Extensions/ExtensionDateFormatter.swift deleted file mode 100644 index 96681db2..00000000 --- a/Cloudinary/Classes/Core/Features/CacheSystem/Extensions/ExtensionDateFormatter.swift +++ /dev/null @@ -1,90 +0,0 @@ -// -// ExtensionDateFormatter.swift -// -// Copyright (c) 2020 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -import Foundation - -extension DateFormatter { - - fileprivate static let cld_posixLocale = Locale(identifier: "en_US_POSIX") - - fileprivate static let cld_gregorianCalendar : Calendar = { - - var calendar = Calendar(identifier: Calendar.Identifier.gregorian) - calendar.timeZone = TimeZone(secondsFromGMT: 0)! - return calendar - }() - - /// - /// - /// - internal static let cld_rfc1123 : DateFormatter = { - - let formatter = DateFormatter() - formatter.locale = cld_posixLocale - formatter.calendar = cld_gregorianCalendar - formatter.timeZone = cld_gregorianCalendar.timeZone - formatter.dateFormat = "EEE',' dd MMM yyyy HH':'mm':'ss 'GMT'" - formatter.isLenient = false - return formatter - }() - - /// - /// - /// - internal static let cld_rfc850 : DateFormatter = { - - let formatter = DateFormatter() - formatter.locale = cld_posixLocale - formatter.calendar = cld_gregorianCalendar - formatter.timeZone = cld_gregorianCalendar.timeZone - formatter.dateFormat = "EEEE',' dd'-'MMM'-'yy HH':'mm':'ss 'GMT'" - formatter.isLenient = false - // From RFC 2616 Section 19.3 Tolerant Applications: - // > HTTP/1.1 clients and caches SHOULD assume that an RFC-850 date - // > which appears to be more than 50 years in the future is in fact - // > in the past (this helps solve the "year 2000" problem). - //DateComponents(year: -49) - var dateComponents = DateComponents() - dateComponents.year = -49 - formatter.twoDigitStartDate = (cld_gregorianCalendar as NSCalendar).date(byAdding: dateComponents, to: Date(), options: []) - return formatter - }() - - /// - /// - /// - internal static let cld_asctime : DateFormatter = { - - let formatter = DateFormatter() - formatter.locale = cld_posixLocale - formatter.calendar = cld_gregorianCalendar - formatter.timeZone = cld_gregorianCalendar.timeZone - // NB: asctime specifies day as ( 2DIGIT | ( SP 1DIGIT ) ). There's no way to represent this with a - // date format, ICU seems to treat stretches of consecutive whitespace all as a single space, so this should - // still parse just fine. Luckily we don't have to generate these strings. - formatter.dateFormat = "EEE MMM dd HH':'mm':'ss yyyy" - formatter.isLenient = false - return formatter - }() -} diff --git a/Cloudinary/Classes/Core/Features/CacheSystem/Extensions/ExtensionHTTPURLResponse.swift b/Cloudinary/Classes/Core/Features/CacheSystem/Extensions/ExtensionHTTPURLResponse.swift deleted file mode 100644 index 7c40d235..00000000 --- a/Cloudinary/Classes/Core/Features/CacheSystem/Extensions/ExtensionHTTPURLResponse.swift +++ /dev/null @@ -1,209 +0,0 @@ -// -// ExtensionHTTPURLResponse.swift -// -// Copyright (c) 2020 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -import Foundation - -extension HTTPURLResponse { - - struct Header { - - struct CacheControl : Equatable { - - var noCache : Bool { return values.contains("no-cache") } - var noStore : Bool { return values.contains("no-store") } - var `public` : Bool { return values.contains("public" ) } - var `private`: Bool { return values.contains("private") } - var maxAge : Int? { return value(for: "max-age" ).flatMap(Int.init) } - var sMaxAge : Int? { return value(for: "s-maxage").flatMap(Int.init) } - var noTransform : Bool { return values.contains("no-transform" ) } - var mustRevalidate : Bool { return values.contains("must-revalidate" ) } - var proxyRevalidate : Bool { return values.contains("proxy-revalidate") } - - init(string: String) { - values = string.replacingOccurrences(of: " ", with: String()).split(separator: ",") - } - - private let values : [Substring] - private func value(for key: String) -> String? { - return values.filter { $0.contains(key) }.first.flatMap { $0.split(separator: "=").last }.map(String.init) - } - } - struct FieldKey : Equatable { - - static let cacheControl = FieldKey("Cache-Control") - static let contentType = FieldKey("Content-Type") - static let date = FieldKey("Date") - static let lastModified = FieldKey("Last-Modified") - static let expires = FieldKey("Expires") - static let pragma = FieldKey("Pragma") - static let etag = FieldKey("Etag") - - let rawValue: String - - init(_ key: String) { - rawValue = key - } - - static func == (lhs: FieldKey, rhs: FieldKey) -> Bool { - return lhs.rawValue == rhs.rawValue - } - } - - - let fields : [AnyHashable:Any] - - func value(for key: FieldKey) -> String? { - return fields[key.rawValue] as? String - } - - /// MARK: - Computed Properties - var cacheControl: CacheControl? { return value(for: .cacheControl).flatMap(CacheControl.init) } - - var contentType : String? { return value(for: .contentType) } - - var date : Date? { - - guard let dateString = value(for: .date) else { return nil } - return DateFormatter.cld_rfc1123.date(from: dateString) ?? DateFormatter.cld_rfc850.date(from: dateString) ?? DateFormatter.cld_asctime.date(from: dateString) - } - var expires : Date? { - - guard let dateString = value(for: .expires) else { return nil } - return DateFormatter.cld_rfc1123.date(from: dateString) ?? DateFormatter.cld_rfc850.date(from: dateString) ?? DateFormatter.cld_asctime.date(from: dateString) - } - var lastModified : Date? { - - guard let dateString = value(for: .lastModified) else { return nil } - return DateFormatter.cld_rfc1123.date(from: dateString) ?? DateFormatter.cld_rfc850.date(from: dateString) ?? DateFormatter.cld_asctime.date(from: dateString) - } - - var pragma : String? { return value(for: .pragma) } - var etag : String? { return value(for: .etag ) } - } - - var cld_header : Header { - return Header(fields: allHeaderFields) - } - - fileprivate var cld_validStatusCode: Bool { - switch statusCode - { - case 200:fallthrough - case 203:fallthrough - case 300:fallthrough - case 301:fallthrough - case 302:fallthrough - case 307:fallthrough - case 410:return true - default: - // Uncacheable response status code - return false - } - } - - var cld_code : HTTPStatusCode? { - return HTTPStatusCode(rawValue: statusCode) - } - - /// Parses a header value that is formatted like the "Date" HTTP header. - /// - /// This parses the specific format allowed for the "Date" header, and any - /// other header that uses the `HTTP-date` production. - /// - /// See [section 3.3.1 of RFC 2616][RFC] for details. - /// - /// [RFC]: https://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3.1 - /// - /// - Parameter dateString: The string value of the HTTP header. - /// - Returns: An `Date`, or `nil` if `dateString` contains an invalid format. - - internal func cld_expirationDate(forCache configuration: CLDURLCacheConfiguration) -> Date? - { - // Check Pragma: no-cache - if let pragma = cld_header.pragma , pragma.lowercased().contains("no-cache") - { - // Uncacheable response - return nil; - } - - // Define "now" based on the request - let currentDate = cld_header.date ?? Date() - - // Look at info from the Cache-Control: max-age=n header - if let cacheControl = cld_header.cacheControl { - - if cacheControl.noStore { - // Can't be cached - return nil - } - - if let maxAge = cacheControl.maxAge { - - switch maxAge > 0 { - case true : return Date(timeInterval: TimeInterval(maxAge), since: currentDate) - case false: return nil - } - } - } - - // If not Cache-Control found, look at the Expires header - if let expiresDate = cld_header.expires { - - let expirationInterval = expiresDate.timeIntervalSince(currentDate) - switch expirationInterval > 0 { - case true : - // Convert remote expiration date to local expiration date - return Date(timeIntervalSinceNow: expirationInterval) - case false: - // If the Expires header can't be parsed or is expired, do not cache - return nil - } - } - - switch statusCode - { - case 302: fallthrough - case 307: - // If not explict cache control defined, do not cache those status - return nil; - default: break - } - - // If no cache control defined, try some heristic to determine an expiration date - if let lastModifiedDate = cld_header.lastModified { - - // Define the age of the document by comparing the Date header with the Last-Modified header - let lastModifiedInterval = currentDate.timeIntervalSince(lastModifiedDate) - - switch lastModifiedInterval > 0 - { - case true : return Date(timeIntervalSinceNow: lastModifiedInterval * configuration.lastModificationFraction) - case false: return nil - } - } - - // If nothing permitted to define the cache expiration delay nor to restrict its cacheability, use a default cache expiration delay - return Date(timeInterval: TimeInterval(configuration.expirationDelayDefault), since: currentDate) - } -} diff --git a/Cloudinary/Classes/Core/Features/CacheSystem/Extensions/ExtensionURL.swift b/Cloudinary/Classes/Core/Features/CacheSystem/Extensions/ExtensionURL.swift deleted file mode 100644 index b6a872b4..00000000 --- a/Cloudinary/Classes/Core/Features/CacheSystem/Extensions/ExtensionURL.swift +++ /dev/null @@ -1,36 +0,0 @@ -// -// ExtensionURL.swift -// -// Copyright (c) 2020 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -import Foundation - -extension Foundation.URL -{ - var cld_URLBasePathWithoutFragment : URL { - - guard var components = URLComponents(string: self.absoluteString) else { return self } - components.fragment = nil - guard let componentsURL = components.url else { return self } - return componentsURL - } -} diff --git a/Cloudinary/Classes/Core/Features/CacheSystem/Extensions/ExtensionURLRequest.swift b/Cloudinary/Classes/Core/Features/CacheSystem/Extensions/ExtensionURLRequest.swift deleted file mode 100644 index ec389501..00000000 --- a/Cloudinary/Classes/Core/Features/CacheSystem/Extensions/ExtensionURLRequest.swift +++ /dev/null @@ -1,46 +0,0 @@ -// -// ExtensionURLRequest.swift -// -// Copyright (c) 2020 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -import Foundation - -extension Foundation.URLRequest -{ - var cld_URLRequestWithoutFragment : URLRequest { - guard let URLObject = url else { return self } - - var request = URLRequest(url: URLObject.cld_URLBasePathWithoutFragment) - request.cachePolicy = cachePolicy - request.timeoutInterval = timeoutInterval - request.mainDocumentURL = mainDocumentURL - request.networkServiceType = networkServiceType - request.allowsCellularAccess = allowsCellularAccess - request.httpMethod = httpMethod - request.allHTTPHeaderFields = allHTTPHeaderFields - request.httpBody = httpBody - request.httpBodyStream = httpBodyStream - request.httpShouldHandleCookies = httpShouldHandleCookies - request.httpShouldUsePipelining = httpShouldUsePipelining - return request - } -} diff --git a/Cloudinary/Classes/Core/Features/CacheSystem/Extensions/ExtensionURLRequestCachePolicy.swift b/Cloudinary/Classes/Core/Features/CacheSystem/Extensions/ExtensionURLRequestCachePolicy.swift deleted file mode 100644 index 71cef3b4..00000000 --- a/Cloudinary/Classes/Core/Features/CacheSystem/Extensions/ExtensionURLRequestCachePolicy.swift +++ /dev/null @@ -1,42 +0,0 @@ -// -// ExtensionURLRequestCachePolicy.swift -// -// Copyright (c) 2020 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -import Foundation - -extension NSURLRequest.CachePolicy : CustomStringConvertible -{ - public var description: String { - switch self { - case .useProtocolCachePolicy : return "useProtocolCachePolicy" - case .reloadIgnoringLocalCacheData : return "reloadIgnoringLocalCacheData" - case .reloadIgnoringLocalAndRemoteCacheData : return "reloadIgnoringLocalAndRemoteCacheData" - case .returnCacheDataElseLoad : return "returnCacheDataElseLoad" - case .returnCacheDataDontLoad : return "returnCacheDataDontLoad" - case .reloadRevalidatingCacheData : return "reloadRevalidatingCacheData" - #if swift(>=5.0) - @unknown default: return "Unknown cache policy" - #endif - } - } -} diff --git a/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseAccess/StorehouseAccessor.swift b/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseAccess/StorehouseAccessor.swift deleted file mode 100755 index e1cdd693..00000000 --- a/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseAccess/StorehouseAccessor.swift +++ /dev/null @@ -1,130 +0,0 @@ -// -// StorehouseAccessor.swift -// -// Copyright (c) 2020 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -import Foundation -import Dispatch -/// -/// -/// -internal class StorehouseAccessor -{ - /// MARK: - Typealias - internal typealias Item = StoredItem - - /// MARK: - Public Properties - internal var storehouse : StorehouseHybrid - internal let accessQueue : DispatchQueue - - internal var memoryCapacity : Int { - var value : Int! - accessQueue.sync { value = storehouse.memoryCapacity } - return value - } - - internal var diskCapacity : Int { - var value : Int! - accessQueue.sync { value = storehouse.diskCapacity } - return value - } - - internal var currentMemoryUsage : Int { - var value : Int! - accessQueue.sync { value = storehouse.currentMemoryUsage } - return value - } - - internal var currentDiskUsage: Int { - var value : Int! - accessQueue.sync { value = storehouse.currentDiskUsage } - return value - } - - /// MARK: - Initializers - internal init(storage: StorehouseHybrid, queue: DispatchQueue) - { - self.storehouse = storage - self.accessQueue = queue - } - - internal func replaceStorage(_ storage: StorehouseHybrid) - { - accessQueue.sync(flags: [.barrier]) { - self.storehouse = storage - } - } -} -extension StorehouseAccessor : StorehouseProtocol -{ - @discardableResult - internal func entry(forKey key: String) throws -> StorehouseEntry - { - var entry : StorehouseEntry! - try accessQueue.sync { - entry = try storehouse.entry(forKey: key) - } - return entry - } - - internal func removeObject(forKey key: String) throws - { - try accessQueue.sync(flags: [.barrier]) { - try self.storehouse.removeObject(forKey: key) - } - } - - internal func setObject(_ object: Item, forKey key: String, expiry: StorehouseExpiry? = nil) throws - { - try accessQueue.sync(flags: [.barrier]) { - try storehouse.setObject(object, forKey: key, expiry: expiry) - } - } - - internal func removeAll() throws - { - try accessQueue.sync(flags: [.barrier]) { - try storehouse.removeAll() - } - } - - internal func removeExpiredObjects() throws - { - try accessQueue.sync(flags: [.barrier]) { - try storehouse.removeExpiredObjects() - } - } - - internal func removeStoredObjects(since date: Date) throws - { - try accessQueue.sync(flags: [.barrier]) { - try storehouse.removeStoredObjects(since: date) - } - } - - internal func removeObjectIfExpired(forKey key: String) throws - { - try accessQueue.sync(flags: [.barrier]) { - try storehouse.removeObjectIfExpired(forKey: key) - } - } -} diff --git a/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseAnyType/StorehouseAny.swift b/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseAnyType/StorehouseAny.swift deleted file mode 100644 index b5c30bc4..00000000 --- a/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseAnyType/StorehouseAny.swift +++ /dev/null @@ -1,78 +0,0 @@ -// -// StorehouseAny.swift -// -// Copyright (c) 2020 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -import Foundation -/// -/// -/// -internal class StorehouseAny : StorehouseProtocol -{ - /// MARK: - Typealias - internal typealias Item = StoredItem - - /// MARK: - Types - - /// MARK: - Fileprivate Properties - /// MARK: - Initializers - internal init() - { - - } - - @discardableResult - internal func entry(forKey key: String) throws -> StorehouseEntry - { - fatalError("You must override this method") - } - - internal func removeObject(forKey key: String) throws - { - fatalError("You must override this method") - } - - internal func setObject(_ object: Item, forKey key: String, expiry: StorehouseExpiry? = nil) throws - { - fatalError("You must override this method") - } - - internal func removeAll() throws - { - fatalError("You must override this method") - } - - internal func removeExpiredObjects() throws - { - fatalError("You must override this method") - } - - internal func removeStoredObjects(since date: Date) throws - { - fatalError("You must override this method") - } - - internal func removeObjectIfExpired(forKey key: String) throws - { - fatalError("You must override this method") - } -} diff --git a/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseAnyType/StorehouseAnyFileSystem.swift b/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseAnyType/StorehouseAnyFileSystem.swift deleted file mode 100644 index c186a5f7..00000000 --- a/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseAnyType/StorehouseAnyFileSystem.swift +++ /dev/null @@ -1,44 +0,0 @@ -// -// StorehouseAnyFileSystem.swift -// -// Copyright (c) 2020 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -import Foundation -/// -/// -/// -internal class StorehouseAnyFileSystem : StorehouseAny , StorehouseFileSystemProtocol -{ - // MARK: - Types - - // MARK: - Properties - - /// - /// The total memory capacity of the cache in bytes. - /// - internal var diskCapacity : Int { return NSNotFound } - - /// - /// The current total memory usage in bytes of all images stored within the cache. - /// - internal var currentDiskUsage : Int { return NSNotFound } -} diff --git a/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseAnyType/StorehouseAnyInMemory.swift b/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseAnyType/StorehouseAnyInMemory.swift deleted file mode 100644 index 57c03b93..00000000 --- a/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseAnyType/StorehouseAnyInMemory.swift +++ /dev/null @@ -1,44 +0,0 @@ -// -// StorehouseAnyInMemory.swift -// -// Copyright (c) 2020 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -import Foundation -/// -/// -/// -internal class StorehouseAnyInMemory : StorehouseAny , StorehouseMemoryProtocol -{ - // MARK: - Types - - // MARK: - Properties - - /// - /// The total memory capacity of the cache in bytes. - /// - internal var memoryCapacity : Int { return NSNotFound } - - /// - /// The current total memory usage in bytes of all images stored within the cache. - /// - internal var currentMemoryUsage : Int { return NSNotFound } -} diff --git a/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseConfiguration/StorehouseConfigurationAutoPurging.swift b/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseConfiguration/StorehouseConfigurationAutoPurging.swift deleted file mode 100644 index bd31e2fb..00000000 --- a/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseConfiguration/StorehouseConfigurationAutoPurging.swift +++ /dev/null @@ -1,72 +0,0 @@ -// -// StorehouseConfigurationAutoPurging.swift -// -// Copyright (c) 2020 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -import Foundation -/// -/// -/// -internal struct StorehouseConfigurationAutoPurging -{ - /// - /// Expiry date that will be applied by default for every added object - /// if it's not overridden in the add(key: object: expiry: completion:) method - /// - internal let expiry : StorehouseExpiry - - /// - /// In-memory capacity of the receiver. - /// At the time this call is made, the in-memory cache will truncate its contents to the size given, if necessary. - /// The in-memory capacity, measured in bytes, for the receiver. - /// - internal let memoryCapacity : Int - - /// - /// The preferred memory usage after purge in bytes. - /// During a purge, objects will be purged until the memory capacity drops below this limit. - /// - internal let preferredMemoryUsageAfterPurge : Int - - /// - /// Initialies the `StorehouseConfigurationAutoPurging` instance with the given memory capacity and - /// preferred memory usage after purge limit. - /// - /// Please note, the memory capacity must always be greater than or equal to the preferred memory usage after purge. - /// - /// - Parameters: - /// - expiry : Expiry date that will be applied by default for every added object - /// - capacity : The total memory capacity of the cache in bytes. `100 MB` by default. - /// - preferredUsage: The preferred memory usage after purge in bytes. ` 60 MB` by default. - /// - /// - Returns: The new `StorehouseConfigurationAutoPurging` instance. - /// - internal init(expiry: StorehouseExpiry = .never, - memory capacity: Int = 100_000_000, - preferredMemoryUsageAfterPurge preferredUsage: Int = 60_000_000 - ) - { - self.expiry = expiry - self.memoryCapacity = capacity - self.preferredMemoryUsageAfterPurge = preferredUsage - } -} diff --git a/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseConfiguration/StorehouseConfigurationDisk.swift b/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseConfiguration/StorehouseConfigurationDisk.swift deleted file mode 100644 index 10eabe23..00000000 --- a/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseConfiguration/StorehouseConfigurationDisk.swift +++ /dev/null @@ -1,66 +0,0 @@ -// -// StorehouseConfigurationDisk.swift -// -// Copyright (c) 2020 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -import Foundation -/// -/// -/// -internal struct StorehouseConfigurationDisk -{ - /// - /// The name of disk storage, this will be used as folder name within directory - /// - internal let name : String - - /// - /// Expiry date that will be applied by default for every added object - /// if it's not overridden in the add(key: object: expiry:) method - /// - internal let expiry : StorehouseExpiry - - /// - /// Maximum size of the disk cache storage (in bytes) - /// - internal let maximumSize : Int - - /// - /// Data protection is used to store files in an encrypted format on disk and to decrypt them on demand. - /// Support only on iOS and tvOS. - /// - internal let protectionType : FileProtectionType? - - /// - /// - /// - internal init(name: String, - expiry: StorehouseExpiry = .never, - maxSize: Int = 0, - protectionType: FileProtectionType? = nil) - { - self.name = name - self.expiry = expiry - self.maximumSize = maxSize - self.protectionType = protectionType - } -} diff --git a/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseConfiguration/StorehouseConfigurationInMemory.swift b/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseConfiguration/StorehouseConfigurationInMemory.swift deleted file mode 100644 index 604b4b44..00000000 --- a/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseConfiguration/StorehouseConfigurationInMemory.swift +++ /dev/null @@ -1,60 +0,0 @@ -// -// StorehouseConfigurationInMemory.swift -// -// Copyright (c) 2020 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -import Foundation -/// -/// -/// -internal struct StorehouseConfigurationInMemory -{ - /// - /// Expiry date that will be applied by default for every added object - /// if it's not overridden in the add(key: object: expiry: completion:) method - /// - internal let expiry : StorehouseExpiry - - /// - /// The maximum number of objects in memory the cache should hold. - /// If 0, there is no count limit. The default value is 0. - /// - internal let countLimit : UInt - - /// - /// The maximum total cost that the cache can hold before it starts evicting objects. - /// If 0, there is no total cost limit. The default value is 0 - /// - internal let totalCostLimit : UInt - - /// - /// - /// - internal init(expiry: StorehouseExpiry = .never, - countLimit: UInt = 0, - totalCostLimit: UInt = 0) - { - self.expiry = expiry - self.countLimit = countLimit - self.totalCostLimit = totalCostLimit - } -} diff --git a/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseContent/StorehouseEntry.swift b/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseContent/StorehouseEntry.swift deleted file mode 100755 index 25cefe88..00000000 --- a/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseContent/StorehouseEntry.swift +++ /dev/null @@ -1,55 +0,0 @@ -// -// StorehouseEntry.swift -// -// Copyright (c) 2020 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -import Foundation -/// -/// A wrapper around cached object and its expiry date. -/// -internal struct StorehouseEntry -{ - /// - /// Cached object - /// - internal let object : Item - - /// - /// Expiry date - /// - internal let expiry : StorehouseExpiry - - /// - /// File path to the cached object - /// - internal let filePath: String? - - /// - /// - /// - init(object: Item, expiry: StorehouseExpiry, filePath: String? = nil) - { - self.object = object - self.expiry = expiry - self.filePath = filePath - } -} diff --git a/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseContent/StorehouseExpiry.swift b/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseContent/StorehouseExpiry.swift deleted file mode 100755 index c9feb1f6..00000000 --- a/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseContent/StorehouseExpiry.swift +++ /dev/null @@ -1,76 +0,0 @@ -// -// StorehouseExpiry.swift -// -// Copyright (c) 2020 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -import Foundation -/// -/// Helper enum to set the expiration date -/// -internal enum StorehouseExpiry -{ - /// - /// Object will be expired in the nearest future - /// - case never - - /// - /// Object will be expired in the nearest future - /// - case secondsFrom1970(TimeInterval) - - /// - /// Object will be expired on the specified date - /// - case date(Date) - - /// - /// Returns the appropriate date object - /// - internal var date : Date { - - switch self { - case .never: - // Ref: http://lists.apple.com/archives/cocoa-dev/2005/Apr/msg01833.html - return Date(timeIntervalSince1970: 60 * 60 * 24 * 365 * 68) // Date.distantFuture - - case .secondsFrom1970(let interval): - return Date(timeIntervalSince1970: interval) - - case .date(let date): - return date - } - } - - /// - /// Checks if cached object is expired according to expiration date - /// - internal var isExpired : Bool { - return date.cld_inThePast - } - /// - /// Checks if cached object is expired according to expiration date - /// - internal func isExpired(for base: Date) -> Bool { - return date.timeIntervalSince1970 - base.timeIntervalSince1970 < 0 - } -} diff --git a/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseContent/StorehouseTransformer.swift b/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseContent/StorehouseTransformer.swift deleted file mode 100755 index 04640ba7..00000000 --- a/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseContent/StorehouseTransformer.swift +++ /dev/null @@ -1,59 +0,0 @@ -// -// StorehouseTransformer.swift -// -// Copyright (c) 2020 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -import Foundation -/// -/// -/// -internal class StorehouseTransformer -{ - /// - /// - /// - internal typealias StorehouseEncode = (Item) throws -> Data - - /// - /// - /// - internal typealias StorehouseDecode = (Data) throws -> Item - - /// - /// - /// - let toData : StorehouseEncode - - /// - /// - /// - let fromData : StorehouseDecode - - /// - /// - /// - internal init(toData: @escaping StorehouseEncode, fromData: @escaping StorehouseDecode) - { - self.toData = toData - self.fromData = fromData - } -} diff --git a/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseHybrid/StorehouseHybrid.swift b/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseHybrid/StorehouseHybrid.swift deleted file mode 100755 index f29e03f3..00000000 --- a/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseHybrid/StorehouseHybrid.swift +++ /dev/null @@ -1,108 +0,0 @@ -// -// StorehouseHybrid.swift -// -// Copyright (c) 2020 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -import Foundation -/// -/// Use both memory and disk storage. Try on memory first. -/// -internal final class StorehouseHybrid : StorehouseAny -{ - /// MARK: - Public Properties - internal let memoryStorage : StorehouseAnyInMemory - internal let diskStorage : StorehouseAnyFileSystem - - /// MARK: - Computed Public Properties - internal var memoryCapacity : Int { - return memoryStorage.memoryCapacity - } - - internal var diskCapacity : Int { - return diskStorage.diskCapacity - } - - internal var currentMemoryUsage : Int { - return memoryStorage.currentMemoryUsage - } - - internal var currentDiskUsage: Int { - return diskStorage.currentDiskUsage - } - - /// MARK: - Initializers - internal init(inMemory memory: StorehouseAnyInMemory, onDisk disk: StorehouseAnyFileSystem) - { - self.memoryStorage = memory - self.diskStorage = disk - } - // MARK: - StorehouseHybridProtocol - @discardableResult - internal override func entry(forKey key: String) throws -> StorehouseEntry - { - do { - return try memoryStorage.entry(forKey: key) - } - catch { - let entry = try diskStorage.entry(forKey: key) - // set back to memoryStorage - try memoryStorage.setObject(entry.object, forKey: key, expiry: entry.expiry) - return entry - } - } - - internal override func removeObject(forKey key: String) throws - { - try memoryStorage.removeObject(forKey: key) - try diskStorage.removeObject(forKey: key) - } - - internal override func setObject(_ object: Item, forKey key: String, expiry: StorehouseExpiry? = nil) throws - { - try memoryStorage.setObject(object, forKey: key, expiry: expiry) - try diskStorage.setObject(object, forKey: key, expiry: expiry) - } - - internal override func removeAll() throws - { - try memoryStorage.removeAll() - try diskStorage.removeAll() - } - - internal override func removeExpiredObjects() throws - { - try memoryStorage.removeExpiredObjects() - try diskStorage.removeExpiredObjects() - } - - internal override func removeStoredObjects(since date: Date) throws - { - try memoryStorage.removeStoredObjects(since: date) - try diskStorage.removeStoredObjects(since: date) - } - - internal override func removeObjectIfExpired(forKey key: String) throws - { - try memoryStorage.removeObjectIfExpired(forKey: key) - try diskStorage.removeObjectIfExpired(forKey: key) - } -} diff --git a/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseProtocol.swift b/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseProtocol.swift deleted file mode 100755 index 8e840dc8..00000000 --- a/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseProtocol.swift +++ /dev/null @@ -1,152 +0,0 @@ -// -// StorehouseProtocol.swift -// -// Copyright (c) 2020 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -import Foundation -/// -/// A protocol used for saving and loading from storehouse -/// -internal protocol StorehouseProtocol -{ - /// The generic type of the protocol - associatedtype Item - - /// - /// Tries to retrieve the object from the Storehouse. - /// - Parameter key: Unique key to identify the object in the cache - /// - Returns: Cached object or nil if not found - /// - @discardableResult - func object(forKey key: String) throws -> Item - - /// - /// Get cache entry which includes object with metadata. - /// - Parameter key: Unique key to identify the object in the cache - /// - Returns: Object wrapper with metadata or nil if not found - /// - @discardableResult - func entry(forKey key: String) throws -> StorehouseEntry - - /// - /// Removes the object by the given key. - /// - Parameter key: Unique key to identify the object. - /// - func removeObject(forKey key: String) throws - - /// - /// Saves passed object. - /// - Parameter key: Unique key to identify the object in the cache. - /// - Parameter object: Object that needs to be cached. - /// - Parameter expiry: Overwrite expiry for this object only. - /// - func setObject(_ object: Item, forKey key: String, expiry: StorehouseExpiry?) throws - - /// - /// Check if an object exist by the given key. - /// - Parameter key: Unique key to identify the object. - /// - @discardableResult - func existsObject(forKey key: String) throws -> Bool - - /// - /// Removes all objects from the cache storage. - /// - func removeAll() throws - - /// - /// Clears all expired objects. - /// - func removeExpiredObjects() throws - - /// - /// Clears all expired objects. - /// - func removeStoredObjects(since date: Date) throws - - /// - /// Removed object for a given key only if it's expired - /// - /// - Parameter key: Unique key to identify the object in the storehouse - /// - func removeObjectIfExpired(forKey key: String) throws - - /// - /// Check if an expired object by the given key. - /// - Parameter key: Unique key to identify the object. - /// - @discardableResult - func isExpiredObject(forKey key: String) throws -> Bool -} -internal extension StorehouseProtocol -{ - @discardableResult - func object(forKey key: String) throws -> Item { - - return try entry(forKey: key).object - } - - @discardableResult - func existsObject(forKey key: String) throws -> Bool { - - do { - try object(forKey: key) - return true - } - catch { - return false - } - } - - @discardableResult - func isExpiredObject(forKey key: String) throws -> Bool { - - do { - let anEntry = try entry(forKey: key) - return anEntry.expiry.isExpired - } - catch { - return true - } - } -} -/// -/// A protocol used for saving and loading from in memory storehouse -/// -internal protocol StorehouseMemoryProtocol : StorehouseProtocol -{ - var memoryCapacity : Int { get } - var currentMemoryUsage : Int { get } -} -/// -/// A protocol used for saving and loading from file system storehouse -/// -internal protocol StorehouseFileSystemProtocol : StorehouseProtocol -{ - var diskCapacity : Int { get } - var currentDiskUsage : Int { get } -} - -/// -/// A protocol used for saving and loading from a hybrid storehouse -/// -internal typealias StorehouseHybridProtocol = StorehouseMemoryProtocol & StorehouseFileSystemProtocol diff --git a/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseType/StorehouseAutoPurging.swift b/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseType/StorehouseAutoPurging.swift deleted file mode 100644 index be861de8..00000000 --- a/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseType/StorehouseAutoPurging.swift +++ /dev/null @@ -1,327 +0,0 @@ -// -// StorehouseAutoPurging.swift -// -// Copyright (c) 2020 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -import UIKit - -import Foundation -/// -/// The `StorehouseAutoPurging` in an in-memory storehouse used to store StoredItem up to a given memory capacity. When -/// the memory capacity is reached, the cache is sorted by last access date, then the oldest entry is continuously -/// purged until the preferred memory usage after purge is met. Each time an entry is accessed through the cache, the -/// internal access date of the entry is updated. -/// -internal final class StorehouseAutoPurging : StorehouseAnyInMemory -{ - // MARK: - Types - - /// - /// - /// - fileprivate class MemoryCapsule - { - /// - /// - /// - fileprivate let identifier : String - - /// - /// - /// - fileprivate let content : StorehouseEntry - - /// - /// - /// - fileprivate let totalBytes : Int - - /// - /// - /// - fileprivate var lastAccessDate : Date - - /// - /// - /// - fileprivate let transformer : StorehouseTransformer - - /// - /// - /// - fileprivate init(identifier: String, content entry: StorehouseEntry, transformer: StorehouseTransformer) throws - { - let object = entry.object - let storedData = try transformer.toData(object) - - self.identifier = identifier - self.content = entry - self.lastAccessDate = Date() - self.transformer = transformer - self.totalBytes = storedData.count - } - - func accessContent() -> StorehouseEntry { - - lastAccessDate = Date() - return content - } - } - - // MARK: - Properties - - /// - /// The total memory capacity of the cache in bytes. - /// - internal override var memoryCapacity : Int { - return configuration.memoryCapacity - } - - /// - /// The current total memory usage in bytes of all images stored within the cache. - /// - internal override var currentMemoryUsage : Int { - var value : Int = 0 - synchronizationQueue.sync { value = self.memoryUsage } - return value - } - - /// - /// The preferred memory usage after purge in bytes. - /// During a purge , images will be purged until the memory capacity drops below this limit. - /// - internal var preferredMemoryUsageAfterPurge : Int { - return configuration.preferredMemoryUsageAfterPurge - } - - /// MARK: - Fileprivate Properties - - /// - /// The current memory usage, for internal use - /// - fileprivate var memoryUsage : Int - - /// Memory cache keys - fileprivate var keys = Set() - - /// Memory cache - fileprivate var cachedMemoryCapsules : [String:MemoryCapsule] - - /// - fileprivate let synchronizationQueue : DispatchQueue - - /// - /// Configuration - /// - fileprivate let configuration : StorehouseConfigurationAutoPurging - - /// - /// Transformer - /// - fileprivate let transformer : StorehouseTransformer - - // MARK: - Initializers - - /// - /// Initialies the `StorehouseAutoPurging` instance with the given memory capacity and preferred memory usage - /// after purge limit. - /// Please note, the memory capacity must always be greater than or equal to the preferred memory usage after purge. - /// - /// - Parameters: - /// - configuration: A settings object for the auto purging storehouse - /// - transformer : A transformer used for conversion into Data and back - /// - /// - Returns: The new `StorehouseAutoPurging` instance. - /// - internal init(configuration: StorehouseConfigurationAutoPurging, transformer : StorehouseTransformer) - { - precondition(configuration.memoryCapacity >= configuration.preferredMemoryUsageAfterPurge, - "The `memoryCapacity` must be greater than or equal to `preferredMemoryUsageAfterPurge`") - - self.configuration = configuration - self.transformer = transformer - - self.cachedMemoryCapsules = [String:MemoryCapsule]() - self.memoryUsage = 0 - - self.synchronizationQueue = { - - let queueName = String(format: "com.cloudinary.autopurgingcache-%08x%08x", arc4random(), arc4random()) - return DispatchQueue(label: queueName, attributes: .concurrent) - }() - - super.init() - - #if os(iOS) || os(tvOS) - #if swift(>=4.2) - let notification = UIApplication.didReceiveMemoryWarningNotification - #else - let notification = Notification.Name.UIApplicationDidReceiveMemoryWarning - #endif - NotificationCenter.default.addObserver(self, selector: #selector(StorehouseAutoPurging.removeAll), name: notification, object: nil) - #endif - } - - deinit { - NotificationCenter.default.removeObserver(self) - } - - // MARK: - Fileprivate methods - - /// - /// - /// - fileprivate func removeObjectIfExpired(forKey key: String, since date: Date) throws - { - guard synchronizationQueue.sync(flags: [.barrier], execute: { - !cachedMemoryCapsules.isEmpty - }) else { return } - - let identifier = key - - var capsule : StorehouseAutoPurging.MemoryCapsule? - synchronizationQueue.sync { - capsule = cachedMemoryCapsules[identifier] - } - - let content = try capsule.cld_unwrapOrThrow(error: StorehouseError.notFound).accessContent() - - guard content.expiry.isExpired(for: date) else { return } - try removeObject(forKey: key) - } - - /// - /// Purge stored capsules they are expired - /// - fileprivate func purgeStoredObjectsIfNeeded() - { - guard memoryUsage > memoryCapacity else { return } - - let bytesToPurge = memoryUsage - preferredMemoryUsageAfterPurge - - var sortedCapsules = cachedMemoryCapsules.map { $1 } - sortedCapsules.sort { - - let date1 = $0.lastAccessDate - let date2 = $1.lastAccessDate - - return date1.timeIntervalSince(date2) < 0.0 - } - - var bytesPurged = Int(0) - - clearOverflow: for capsule in sortedCapsules { - - cachedMemoryCapsules.removeValue(forKey: capsule.identifier) - bytesPurged += capsule.totalBytes - - guard bytesPurged >= bytesToPurge else { continue } - break clearOverflow - } - - memoryUsage -= bytesPurged - } - - // MARK: - StorehouseProtocol - - @discardableResult - internal override func entry(forKey key: String) throws -> StorehouseEntry - { - var capsule : StorehouseEntry? - - let identifier = key - synchronizationQueue.sync { - - guard let cachedCapsule = cachedMemoryCapsules[identifier] else { return } - capsule = cachedCapsule.accessContent() - } - return try capsule.cld_unwrapOrThrow(error: StorehouseError.notFound) - } - - internal override func removeObject(forKey key: String) throws - { - let identifier = key - synchronizationQueue.sync(flags: [.barrier]) { - - guard let cachedCapsule = cachedMemoryCapsules.removeValue(forKey: identifier) else { return } - self.memoryUsage -= cachedCapsule.totalBytes - keys.remove(key) - } - } - - internal override func setObject(_ object: Item, forKey key: String, expiry: StorehouseExpiry?) throws - { - let identifier = key - try synchronizationQueue.sync(flags: [.barrier]) { - - let entry = StorehouseEntry(object: object, expiry: .date(expiry?.date ?? configuration.expiry.date)) - let capsule = try MemoryCapsule(identifier: identifier, content: entry, transformer: transformer) - - if let previousCachedCapsule = cachedMemoryCapsules[identifier] { - memoryUsage -= previousCachedCapsule.totalBytes - } - cachedMemoryCapsules[identifier] = capsule - keys.insert(key) - - memoryUsage += capsule.totalBytes - } - - synchronizationQueue.async(flags: [.barrier]) { - self.purgeStoredObjectsIfNeeded() - } - } - - @objc - internal override func removeAll() throws - { - synchronizationQueue.sync(flags: [.barrier]) { - - guard !self.cachedMemoryCapsules.isEmpty else { return } - self.cachedMemoryCapsules.removeAll() - self.memoryUsage = 0 - self.keys.removeAll() - } - } - - internal override func removeExpiredObjects() throws - { - let now = Date() - let allKeys = keys - try allKeys.forEach { - try removeObjectIfExpired(forKey: $0, since: now) - } - } - - internal override func removeStoredObjects(since date: Date) throws - { - let now = Date() - let allKeys = keys - try allKeys.forEach { - try removeObjectIfExpired(forKey: $0, since: now) - } - } - - internal override func removeObjectIfExpired(forKey key: String) throws - { - try removeObjectIfExpired(forKey: key, since: Date()) - } -} diff --git a/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseType/StorehouseInMemory.swift b/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseType/StorehouseInMemory.swift deleted file mode 100755 index 6ae89e87..00000000 --- a/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseType/StorehouseInMemory.swift +++ /dev/null @@ -1,147 +0,0 @@ -// -// StorehouseInMemory.swift -// -// Copyright (c) 2020 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -import Foundation -/// -/// -/// -internal final class StorehouseInMemory: StorehouseAnyInMemory -{ - /// MARK: - Types - /// - /// Helper class to hold cached instance and expiry date. - /// Used in memory storage to work with NSCache. - /// - fileprivate class MemoryCapsule : NSObject - { - /// - /// Object to be cached - /// - let object : Any - - /// - /// Expiration date - /// - let expiry : StorehouseExpiry - - /// - /// Creates a new instance of Capsule. - /// - /// - Parameter value : Object to be cached - /// - Parameter expiry: Expiration date - /// - init(value: Any, expiry: StorehouseExpiry) { - self.object = value - self.expiry = expiry - } - } - - internal override var memoryCapacity : Int { - return NSNotFound - } - - internal override var currentMemoryUsage : Int { - return NSNotFound - } - - /// MARK: - Fileprivate Properties - - /// Memory cache keys - fileprivate var keys = Set() - - /// Memory cache - fileprivate let cache = NSCache() - - /// Configuration - fileprivate let configuration : StorehouseConfigurationInMemory - - /// MARK: - Initializers - internal init(configuration: StorehouseConfigurationInMemory) - { - self.configuration = configuration - self.cache.countLimit = Int(configuration.countLimit) - self.cache.totalCostLimit = Int(configuration.totalCostLimit) - super.init() - } - - fileprivate func removeObjectIfExpired(forKey key: String, since date: Date) throws - { - let aKey = NSString(string: key) - - guard let capsule = cache.object(forKey: aKey) else { return } - guard capsule.expiry.isExpired(for: date) else { return } - try removeObject(forKey: key) - } - - // MARK: - StorehouseProtocol - - @discardableResult - internal override func entry(forKey key: String) throws -> StorehouseEntry - { - let aKey = NSString(string: key) - guard let capsule = cache.object(forKey: aKey) else { throw StorehouseError.notFound } - guard let object = capsule.object as? Item else { throw StorehouseError.typeNotMatch } - return StorehouseEntry(object: object, expiry: capsule.expiry) - } - - internal override func removeObject(forKey key: String) throws - { - let aKey = NSString(string: key) - cache.removeObject(forKey: aKey) - keys.remove(key) - } - - internal override func setObject(_ object: Item, forKey key: String, expiry: StorehouseExpiry? = nil) throws - { - let capsule = MemoryCapsule(value: object, expiry: .date(expiry?.date ?? configuration.expiry.date)) - cache.setObject(capsule, forKey: NSString(string: key)) - keys.insert(key) - } - - internal override func removeAll() throws - { - cache.removeAllObjects() - keys.removeAll() - } - - internal override func removeExpiredObjects() throws - { - let now = Date() - try removeStoredObjects(since: now) - } - - internal override func removeStoredObjects(since date: Date) throws - { - let allKeys = keys - - try allKeys.forEach { - try removeObjectIfExpired(forKey: $0, since: date) - } - } - - internal override func removeObjectIfExpired(forKey key: String) throws - { - try removeObjectIfExpired(forKey: key, since: Date()) - } -} diff --git a/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseType/StorehouseOnDisk.swift b/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseType/StorehouseOnDisk.swift deleted file mode 100755 index 42a325c1..00000000 --- a/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/StorehouseType/StorehouseOnDisk.swift +++ /dev/null @@ -1,376 +0,0 @@ -// -// StorehouseOnDisk.swift -// -// Copyright (c) 2020 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -import Foundation -/// -/// -/// -typealias ResourceObject = (url: Foundation.URL, resourceValues: URLResourceValues) -/// -/// Save objects to file on disk -/// -final internal class StorehouseOnDisk: StorehouseAnyFileSystem -{ - /// MARK: - Types - enum Error : Swift.Error { - case fileEnumeratorFailed - } - - /// MARK: - Properties - - /// - /// Caches Directory URL - /// - fileprivate class var cachesDirectoryURL : URL { - - let urls = FileManager.init().urls(for: .cachesDirectory, in: .userDomainMask) - let directory = urls[urls.endIndex - 1] - return directory - } - - /// - /// The name of the application container - /// - internal var applicationName : String { - return Bundle.main.bundleIdentifier! - } - - /// - /// The name of the cache container - /// - internal var cacheContainerName : String { - return configuration.name - } - - /// - /// The on-disk capacity of the receiver. - /// - /// The on-disk capacity, measured in bytes, for the receiver. - /// On mutation the on-disk cache will truncate its contents to the size given, if necessary. - /// - internal override var diskCapacity : Int { - return configuration.maximumSize - } - - /// - /// Returns the current amount of space consumed by the on-disk storage of the receiver. - /// - /// This size, measured in bytes, indicates the current usage of the on-disk storage. - /// - internal override var currentDiskUsage : Int { - - var diskUsage : Int = 0 - do { - let contents = try fileManager.contentsOfDirectory(atPath: diskFilesFolderURL.path) - - let basePath = diskFilesFolderURL.path - - for pathComponent in contents { - - let filePath = NSString(string: basePath).appendingPathComponent(pathComponent) - let attributes = try fileManager.attributesOfItem(atPath: filePath) - if let fileSize = attributes[.size] as? Int { - diskUsage += fileSize - } - } - } - catch { - diskUsage = NSNotFound - } - return diskUsage - } - - /// - /// The name of the cache folder on disk, containg the different files - /// - internal var diskFolderName : String { - return "CLDURLCache.Cache" - } - - /// - /// - /// - internal lazy var diskFilesFolderURL : URL = { - - let cacheDirectoryURL = StorehouseOnDisk.cachesDirectoryURL - let cacheBaseURL = cacheDirectoryURL.appendingPathComponent(applicationName) - let cacheContainerURL = cacheBaseURL.appendingPathComponent(cacheContainerName) - let finalDirectoryURL = cacheContainerURL.appendingPathComponent(diskFolderName) - return finalDirectoryURL - }() - - /// File manager to read/write to the disk - internal let fileManager : FileManager - - /// Configuration - fileprivate let configuration : StorehouseConfigurationDisk - - /// Transformer used by the system to archive the StoredItem - fileprivate let transformer : StorehouseTransformer - - /// MARK: - Initializers - - /// - /// - /// - internal init(configuration: StorehouseConfigurationDisk, fileManager: FileManager = FileManager.default, transformer: StorehouseTransformer) throws - { - self.configuration = configuration - self.fileManager = fileManager - self.transformer = transformer - - super.init() - - try createDirectoryIfNeeded(at: diskFilesFolderURL, using: fileManager) - - // protection - guard let protectionType = configuration.protectionType else { return } - try setDirectory([.protectionKey:protectionType], using: fileManager, atPath: diskFilesFolderURL.path) - } - - /// - /// Creates a directory at a given url, if it doesnt exists - /// - /// - Parameters: - /// - url : The target directory url - /// - fileManager: File manager to be used by this method - /// - fileprivate func createDirectoryIfNeeded(at url: URL?, using fileManager: FileManager) throws - { - guard let URLObject = url , !fileManager.fileExists(atPath: URLObject.path, isDirectory: nil) else { return } - - do { - try fileManager.createDirectory(atPath: URLObject.path, withIntermediateDirectories: true, attributes: nil) - } - catch let error as NSError { - printLog(.error, text: "Error unable to create directory \(URLObject.path)") - printLog(.error, text: "Error \(error.debugDescription)") - throw error - } - } - - /// - /// Sets attributes on a directory. - /// - /// - Parameters: - /// - attributes : File attributes dictionary to set - /// - fileManager: File manager to be used by this method - /// - path : The file we set the attributes for - /// - fileprivate func setDirectory(_ attributes: [FileAttributeKey: Any], using fileManager: FileManager, atPath path: String) throws { - try fileManager.setAttributes(attributes, ofItemAtPath: path) - } - - /// - /// Builds file name from the key. - /// - /// - Parameter key: Unique key to identify the object in the cache - /// - Returns: A md5 encoded file name - /// - internal func makeFileName(for key: String) -> String - { - let fileName = key.cld_md5() - let fileExtension = URL(fileURLWithPath: key).pathExtension - - switch fileExtension.isEmpty - { - case true : return "\(fileName)" - case false: return "\(fileName).\(fileExtension)" - } - } - - /// - /// Builds file path from the key. - /// - Parameter key: Unique key to identify the object in the cache - /// - Returns: A string path based on key - /// - internal func makeFilePath(for key: String) -> String - { - return diskFilesFolderURL.appendingPathComponent(makeFileName(for: key)).path - } - - /// - /// Extract items information closure from a givent items url array - /// - /// - Parameters: - /// - itemURLs: An array of urls to extract the information - /// - baseDate: The base date used to decide if we need to delete an item - /// - fileprivate func extractItemsInformation(from itemURLs: [URL], comperAgainst baseDate: Date) throws -> (filesToDelete: [URL], resourceObjects: [ResourceObject], totalItemsSize: Int) - { - let resourceKeys: [URLResourceKey] = [ - .isDirectoryKey, - .contentModificationDateKey, - .totalFileAllocatedSizeKey - ] - - var toDelete = [URL]() - var resources = [ResourceObject]() - var totalSize = Int(0) - - for url in itemURLs { - - let resourceValues = try url.resourceValues(forKeys: Set(resourceKeys)) - - guard resourceValues.isDirectory != true else { continue } - - if let expiryDate = resourceValues.contentModificationDate, expiryDate.timeIntervalSince1970 - baseDate.timeIntervalSince1970 < 0 { - toDelete.append(url) - continue - } - - if let fileSize = resourceValues.totalFileAllocatedSize { - totalSize += Int(fileSize) - resources.append( (url: url, resourceValues: resourceValues) ) - } - } - return (filesToDelete: toDelete, resourceObjects: resources, totalItemsSize: totalSize) - } - - /// - /// Removes objects if storage size exceeds max size. - /// - Parameters: - /// - objects : Resource objects to remove - /// - totalSize: Total size - /// - fileprivate func removeResourceObjects(_ objects: [ResourceObject], currentSize: Int) throws { - - guard diskCapacity > 0 && currentSize > diskCapacity else { return } - - var totalSize = currentSize - let targetSize = diskCapacity / 2 - - let sortedFiles = objects.sorted { - - guard let time1 = $0.resourceValues.contentModificationDate?.timeIntervalSinceReferenceDate else { return false } - guard let time2 = $1.resourceValues.contentModificationDate?.timeIntervalSinceReferenceDate else { return false } - return time1 > time2 - } - - clearOverflow: for file in sortedFiles { - - try fileManager.removeItem(at: file.url) - - if let fileSize = file.resourceValues.totalFileAllocatedSize { - totalSize -= Int(fileSize) - } - - guard totalSize >= targetSize else { continue } - break clearOverflow - } - } - - // MARK: - StorehouseProtocol - - @discardableResult - internal override func entry(forKey key: String) throws -> StorehouseEntry - { - let filePath = makeFilePath(for: key) - let data = try Data(contentsOf: URL(fileURLWithPath: filePath)) - let attributes = try fileManager.attributesOfItem(atPath: filePath) - let object = try transformer.fromData(data) - - guard let date = attributes[.modificationDate] as? Date else { throw StorehouseError.malformedFileAttributes } - - return StorehouseEntry(object: object, expiry: .date(date), filePath: filePath) - } - - internal override func removeObject(forKey key: String) throws - { - let filePath = makeFilePath(for: key) - try fileManager.removeItem(atPath: filePath) - } - - internal override func setObject(_ object: Item, forKey key: String, expiry: StorehouseExpiry? = nil) throws - { - let expiry = expiry ?? configuration.expiry - let data = try transformer.toData(object) - let filePath = makeFilePath(for: key) - - _ = fileManager.createFile(atPath: filePath, contents: data, attributes: nil) - try fileManager.setAttributes([.modificationDate: expiry.date], ofItemAtPath: filePath) - } - - internal override func removeAll() throws - { - let fileEnumerator = fileManager.enumerator(at: diskFilesFolderURL, includingPropertiesForKeys: nil) - - guard let storageURLs = fileEnumerator?.allObjects as? [URL] else { - throw Error.fileEnumeratorFailed - } - - var isDirectory = ObjCBool(false) - try storageURLs.forEach { - - guard fileManager.fileExists(atPath: $0.path, isDirectory: &isDirectory) , !isDirectory.boolValue else { return } - try fileManager.removeItem(atPath: $0.path) - } - } - - internal override func removeExpiredObjects() throws - { - try removeStoredObjects(since: Date()) - } - - internal override func removeStoredObjects(since date: Date) throws - { - let resourceKeys: [URLResourceKey] = [ - .isDirectoryKey, - .contentModificationDateKey, - .totalFileAllocatedSizeKey - ] - - let fileEnumerator = fileManager.enumerator( - at: diskFilesFolderURL, - includingPropertiesForKeys: resourceKeys, - options: .skipsHiddenFiles, - errorHandler: nil - ) - - guard let urlArray = fileEnumerator?.allObjects as? [URL] else { - throw Error.fileEnumeratorFailed - } - - let closure = try extractItemsInformation(from: urlArray, comperAgainst: date) - - // Remove expired objects - for url in closure.filesToDelete { - try fileManager.removeItem(at: url) - } - - // Remove objects if storage size exceeds max size - try removeResourceObjects(closure.resourceObjects, currentSize: closure.totalItemsSize) - } - - internal override func removeObjectIfExpired(forKey key: String) throws - { - let filePath = makeFilePath(for: key) - - let attributes = try fileManager.attributesOfItem(atPath: filePath) - - if let expiryDate = attributes[.modificationDate] as? Date, expiryDate.cld_inThePast { - try fileManager.removeItem(atPath: filePath) - } - } -} diff --git a/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/Warehouse.swift b/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/Warehouse.swift deleted file mode 100755 index ccb71988..00000000 --- a/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/Warehouse.swift +++ /dev/null @@ -1,151 +0,0 @@ -// -// Warehouse.swift -// -// Copyright (c) 2020 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -import Foundation -import Dispatch -/// -/// Manage a storehouse with wares, generic over SoredType. -/// -internal final class Warehouse -{ - /// MARK: - Typealias - internal typealias Item = SoredType - - /// MARK: - Private Properties - private let accessor : StorehouseAccessor - private let storehouse : StorehouseHybrid - - /// MARK: - Public Computed Properties - internal var memoryCapacity : Int { - return accessor.memoryCapacity - } - internal var diskCapacity : Int { - return accessor.diskCapacity - } - - internal var currentMemoryUsage : Int { - return accessor.currentMemoryUsage - } - - internal var currentDiskUsage: Int { - return accessor.currentDiskUsage - } - - /// MARK: - Initializers - - /// - /// Initialize a warehouse with configuration options. - /// - /// - Parameters: - /// - memoryConfig: In memory storehouse configuration - /// - diskConfig : Disk storehouse configuration - /// - transformer : A transformer to use for conversion of the stored data into the file system - /// - /// - Throws: Throw StorehouseError if any. - /// - internal convenience init(memoryConfig: StorehouseConfigurationInMemory, diskConfig: StorehouseConfigurationDisk, transformer: StorehouseTransformer) throws - { - let disk = try StorehouseOnDisk(configuration: diskConfig, transformer: transformer) - let memory = StorehouseInMemory(configuration: memoryConfig) - let storage = StorehouseHybrid(inMemory: memory, onDisk: disk) - self.init(hybrid: storage) - } - - /// - /// Initialize a warehouse with configuration options. - /// - /// - Parameters: - /// - memoryConfig: In memory storehouse configuration - /// - diskConfig : Disk storehouse configuration - /// - transformer : A transformer to use for conversion of the stored data into the file system - /// - /// - Throws: Throw StorehouseError if any. - /// - internal convenience init(purgingConfig: StorehouseConfigurationAutoPurging, diskConfig: StorehouseConfigurationDisk, transformer: StorehouseTransformer) throws - { - let disk = try StorehouseOnDisk (configuration: diskConfig, transformer: transformer) - let memory = StorehouseAutoPurging(configuration: purgingConfig, transformer: transformer) - let storage = StorehouseHybrid(inMemory: memory, onDisk: disk) - self.init(hybrid: storage) - } - - /// - /// Initialise a warehouse with a prepared storehouse. - /// - /// - Parameter storage: The storehouse to use - internal init(hybrid storage: StorehouseHybrid) - { - let queue = DispatchQueue(label: "com.cloudinary.accessQueue", attributes: [.concurrent]) - self.storehouse = storage - self.accessor = StorehouseAccessor(storage: storage, queue: queue) - } - - internal func updateCacheCapacity(purgingConfig: StorehouseConfigurationAutoPurging, diskConfig: StorehouseConfigurationDisk, transformer: StorehouseTransformer) throws { - - let disk = try StorehouseOnDisk (configuration: diskConfig, transformer: transformer) - let memory = StorehouseAutoPurging(configuration: purgingConfig, transformer: transformer) - let storage = StorehouseHybrid(inMemory: memory, onDisk: disk) - - accessor.replaceStorage(storage) - } -} - -extension Warehouse : StorehouseProtocol -{ - @discardableResult - internal func entry(forKey key: String) throws -> StorehouseEntry - { - return try accessor.entry(forKey: key) - } - - internal func removeObject(forKey key: String) throws - { - try accessor.removeObject(forKey: key) - } - - internal func setObject(_ object: Item, forKey key: String, expiry: StorehouseExpiry? = nil) throws - { - try accessor.setObject(object, forKey: key, expiry: expiry) - } - - internal func removeAll() throws - { - try accessor.removeAll() - } - - internal func removeExpiredObjects() throws - { - try accessor.removeExpiredObjects() - } - - internal func removeStoredObjects(since date: Date) throws - { - try accessor.removeStoredObjects(since: date) - } - - internal func removeObjectIfExpired(forKey key: String) throws - { - try accessor.removeObjectIfExpired(forKey: key) - } -} diff --git a/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/WarehouseTransformerFactory.swift b/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/WarehouseTransformerFactory.swift deleted file mode 100644 index 6da2a8f3..00000000 --- a/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Core/WarehouseTransformerFactory.swift +++ /dev/null @@ -1,167 +0,0 @@ -// -// WarehouseTransformerFactory.swift -// -// Copyright (c) 2020 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -import Foundation -/// -/// -/// -internal class WarehouseTransformerFactory -{ - /// MARK: - Types - - /// - /// Used to wrap Codable object - /// - internal struct CodableWrapper: Codable - { - enum CodingKeys : String , CodingKey - { - case object - } - - internal let object : CodableType - internal init(object: CodableType) { - self.object = object - } - } - - /// - /// - /// - private init() { } - - /// - /// - /// - internal static func forCodable(ofType: Item.Type) -> StorehouseTransformer - { - let toData : (Item) throws -> Data = { object in - - let wrapper = CodableWrapper(object: object) - let encoder = JSONEncoder() - return try encoder.encode(wrapper) - } - let fromData : (Data) throws -> Item = { data in - - let decoder = JSONDecoder() - return try decoder.decode(CodableWrapper.self, from: data).object - } - - return StorehouseTransformer(toData: toData, fromData: fromData) - } - - /// - /// - /// - internal static func forCoding(ofType: Item.Type) -> StorehouseTransformer - { - let toData : (Item) throws -> Data = { (object) in - - let data = NSMutableData() - let archiver : NSKeyedArchiver - if #available(iOS 12.0, *) { - archiver = NSKeyedArchiver(requiringSecureCoding: false) - } else { - archiver = NSKeyedArchiver(forWritingWith: data) - archiver.requiresSecureCoding = false - } - - archiver.encode(object, forKey: NSKeyedArchiveRootObjectKey) - archiver.finishEncoding() - - let encodedData: Data - if #available(iOS 10.0, *) { - encodedData = archiver.encodedData - } else { - encodedData = data as Data - } - return encodedData as Data - } - let fromData : (Data) throws -> Item = { (data) in - - let unarchiver : NSKeyedUnarchiver - if #available(iOS 12.0, *) { - unarchiver = try! NSKeyedUnarchiver(forReadingFrom: data) - } else { - unarchiver = NSKeyedUnarchiver(forReadingWith: data) - } - - unarchiver.requiresSecureCoding = false - - let object = unarchiver.decodeObject(of: [Item.self], forKey: NSKeyedArchiveRootObjectKey) - unarchiver.finishDecoding() - - return try (object as? Item).cld_unwrapOrThrow(error: StorehouseError.decodingFailed) - } - - return StorehouseTransformer(toData: toData, fromData: fromData) - } - - /// - /// - /// - internal static func forSecuredCoding(ofType: Item.Type) -> StorehouseTransformer - { - let toData : (Item) throws -> Data = { (object) in - - let data = NSMutableData() - let archiver : NSKeyedArchiver - if #available(iOS 12.0, *) { - archiver = NSKeyedArchiver(requiringSecureCoding: true) - } else { - archiver = NSKeyedArchiver(forWritingWith: data) - archiver.requiresSecureCoding = true - } - - archiver.encode(object, forKey: NSKeyedArchiveRootObjectKey) - archiver.finishEncoding() - - let encodedData: Data - if #available(iOS 10.0, *) { - encodedData = archiver.encodedData - } else { - encodedData = data as Data - } - return encodedData as Data - } - let fromData : (Data) throws -> Item = { (data) in - - let unarchiver : NSKeyedUnarchiver - if #available(iOS 12.0, *) { - unarchiver = try! NSKeyedUnarchiver(forReadingFrom: data) - } else { - unarchiver = NSKeyedUnarchiver(forReadingWith: data) - } - - unarchiver.requiresSecureCoding = true - - let object = unarchiver.decodeObject(of: [Item.self], forKey: NSKeyedArchiveRootObjectKey) - unarchiver.finishDecoding() - - return try (object as? Item).cld_unwrapOrThrow(error: StorehouseError.decodingFailed) - } - - return StorehouseTransformer(toData: toData, fromData: fromData) - } -} diff --git a/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Enum/StorehouseError.swift b/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Enum/StorehouseError.swift deleted file mode 100755 index 41b744a9..00000000 --- a/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Enum/StorehouseError.swift +++ /dev/null @@ -1,51 +0,0 @@ -// -// StorehouseError.swift -// -// Copyright (c) 2020 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -import Foundation -/// -/// -/// -internal enum StorehouseError : Error { - - /// Object can not be found - case notFound - - /// Object is found, but casting to requested type failed - case typeNotMatch - - /// The file attributes are malformed - case malformedFileAttributes - - /// Can't perform Decode - case decodingFailed - - /// Can't perform Encode - case encodingFailed - - // /// The storage has been deallocated - // case deallocated - // - // /// Fail to perform transformation to or from Data - // case transformerFail -} diff --git a/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Extension/ExtensionDate.swift b/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Extension/ExtensionDate.swift deleted file mode 100644 index 6d04f976..00000000 --- a/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Extension/ExtensionDate.swift +++ /dev/null @@ -1,33 +0,0 @@ -// -// ExtensionDate.swift -// -// Copyright (c) 2020 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -import Foundation - -extension Date { - - /// Checks if the date is in the past. - internal var cld_inThePast : Bool { - return timeIntervalSinceNow < 0 - } -} diff --git a/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Extension/ExtensionOptional.swift b/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Extension/ExtensionOptional.swift deleted file mode 100644 index 39099b79..00000000 --- a/Cloudinary/Classes/Core/Features/CacheSystem/StorehouseLibrary/Extension/ExtensionOptional.swift +++ /dev/null @@ -1,38 +0,0 @@ -// -// ExtensionOptional.swift -// -// Copyright (c) 2020 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -import Foundation - -extension Optional { - - /// Extract value or throw an error - internal func cld_unwrapOrThrow(error: Error) throws -> Wrapped { - - if let value = self { - return value - } else { - throw error - } - } -} diff --git a/Cloudinary/Classes/Core/Network/CLDNetworkCoordinator.swift b/Cloudinary/Classes/Core/Network/CLDNetworkCoordinator.swift index 6caf6d03..72bf6cea 100644 --- a/Cloudinary/Classes/Core/Network/CLDNetworkCoordinator.swift +++ b/Cloudinary/Classes/Core/Network/CLDNetworkCoordinator.swift @@ -188,24 +188,22 @@ internal class CLDNetworkCoordinator: NSObject { } } -class CLDDownloadCoordinator: CLDNetworkCoordinator, CLDURLCacheDelegate { +class CLDDownloadCoordinator: CLDNetworkCoordinator { + + static var enableCache = true + + static var urlCache = URLCache.init(memoryCapacity: Defines.defaultMaxMemoryCapacity, diskCapacity: Defines.defaultMaxDiskCapacity, diskPath: "") - let imageCache = CLDImageCache(name: Defines.cacheDefaultName) - let urlCache = CLDURLCache(memoryCapacity: Defines.defaultMemoryTotalCostLimit, diskCapacity: Defines.defaultMaxDiskCapacity, diskPath: Defines.cacheAssetDefaultName, configuration: CLDURLCacheConfiguration.defualt) - init(configuration: CLDConfiguration) { let downloadConfiguration = URLSessionConfiguration.default downloadConfiguration.httpAdditionalHeaders = CLDNSessionManager.defaultHTTPHeaders - downloadConfiguration.urlCache = urlCache - // Turn urlCache as default - urlCache.shouldIncludeImages(true) - + downloadConfiguration.urlCache = CLDDownloadCoordinator.urlCache + let downloadAdapter = CLDDefaultNetworkAdapter(configuration: downloadConfiguration) super.init(configuration: configuration, networkAdapter: downloadAdapter) - - urlCache.delegate = self + } override init(configuration: CLDConfiguration, sessionConfiguration: URLSessionConfiguration) { @@ -216,13 +214,9 @@ class CLDDownloadCoordinator: CLDNetworkCoordinator, CLDURLCacheDelegate { super.init(configuration: configuration, networkAdapter: networkAdapter) } - func shouldExclude(response: HTTPURLResponse, for urlCache: CLDURLCache) -> Bool { - - if let contentType = response.cld_header.value(for: .contentType), - contentType.contains("image") { - return true - } - - return false - } +} + +internal struct Defines { + static let defaultMaxMemoryCapacity = 30 * 1024 * 1024 // 30 MB + static let defaultMaxDiskCapacity = 150 * 1024 * 1024 // 150 MB } diff --git a/Cloudinary/Classes/Core/Network/NetworkRequest/CLDNetworkDownloadRequest.swift b/Cloudinary/Classes/Core/Network/NetworkRequest/CLDNetworkDownloadRequest.swift index a2e28015..54835044 100644 --- a/Cloudinary/Classes/Core/Network/NetworkRequest/CLDNetworkDownloadRequest.swift +++ b/Cloudinary/Classes/Core/Network/NetworkRequest/CLDNetworkDownloadRequest.swift @@ -51,20 +51,23 @@ internal class CLDNetworkDownloadRequest: CLDNetworkDataRequestImpl ())?) -> CLDNetworkDataRequest { - request.responseData { response in let statusCode = response.response?.statusCode - if let downloadedData = response.result.value { - - if let statusCode = statusCode, - !self.isAcceptableCode(code: statusCode) { - - let statusCodeError = CLDError.error(code: .unacceptableStatusCode, message: "request error - unacceptable statusCode - \(statusCode)", userInfo: ["statusCode": statusCode]) - completionHandler?(downloadedData, statusCodeError, statusCode) + if let statusCode = statusCode, self.isAcceptableCode(code: statusCode) { + if CLDDownloadCoordinator.enableCache, + let result = response.response, + let data = response.data, + let request = self.request.request, + CLDDownloadCoordinator.urlCache.cachedResponse(for: request) == nil { + let cachedData = CachedURLResponse(response: result, data: data) + CLDDownloadCoordinator.urlCache.storeCachedResponse(cachedData, for: request) + } + completionHandler?(downloadedData, nil, statusCode) } else { - completionHandler?(downloadedData, nil, statusCode) + let statusCodeError = CLDError.error(code: .unacceptableStatusCode, message: "request error - unacceptable statusCode - \(statusCode)", userInfo: ["statusCode": statusCode]) + completionHandler?(downloadedData, statusCodeError, statusCode) } } else if let err = response.result.error { diff --git a/Cloudinary/Classes/Core/Utils/CLDImageCache.swift b/Cloudinary/Classes/Core/Utils/CLDImageCache.swift deleted file mode 100644 index ec3638cd..00000000 --- a/Cloudinary/Classes/Core/Utils/CLDImageCache.swift +++ /dev/null @@ -1,320 +0,0 @@ -// -// CLDImageCache.swift -// -// Copyright (c) 2016 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -import Foundation -import UIKit - - -@objc public enum CLDImageCachePolicy: Int { - case none, memory, disk -} - -internal struct Defines { - static let cacheDefaultName = "defaultImageCache" - static let cacheAssetDefaultName = "defaultAssetCache" - static let cacheBaseName = "com.cloudinary.sdk.imageCache" - static let readWriteQueueName = "com.cloudinary.sdk.imageCache.readWriteQueue" - static let defaultMemoryTotalCostLimit = 30 * 1024 * 1024 // 30 MB - static let defaultMaxDiskCapacity = 150 * 1024 * 1024 // 150 MB - static let thresholdPercentSize = UInt64(0.8) - static let defaultBytesPerPixel = 4 -} - - -internal class CLDImageCache { - - internal var cachePolicy = CLDImageCachePolicy.none - - fileprivate let memoryCache = NSCache() - internal var maxMemoryTotalCost: Int = Defines.defaultMemoryTotalCostLimit { - didSet{ - memoryCache.totalCostLimit = maxMemoryTotalCost - self.clearMemoryCache() - } - } - - fileprivate let diskCacheDir: String - - // Disk Size Control - internal var maxDiskCapacity: UInt64 = UInt64(Defines.defaultMaxDiskCapacity) { - didSet { - clearDiskToMatchCapacityIfNeeded() - } - } - fileprivate var usedCacheSize: UInt64 = 0 - - fileprivate let readWriteQueue: DispatchQueue - - //MARK: - Lifecycle - - init(name: String, diskCachePath: String? = nil) { - - let cacheName = "\(Defines.cacheBaseName).\(name)" - memoryCache.name = cacheName - - // We have to set this manually here since `maxMemoryTotalCost.didSet()` is never triggered during init - memoryCache.totalCostLimit = maxMemoryTotalCost - - let diskPath = diskCachePath ?? NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true).first! - diskCacheDir = diskPath.cldStringByAppendingPathComponent(str: cacheName) - - readWriteQueue = DispatchQueue(label: Defines.readWriteQueueName + name, attributes: []) - - calculateCurrentDiskCacheSize() - clearDiskToMatchCapacityIfNeeded() - - NotificationCenter.default.addObserver(self, selector: #selector(CLDImageCache.clearMemoryCache), name: UIApplication.didReceiveMemoryWarningNotification, object: nil) - } - - deinit { - NotificationCenter.default.removeObserver(self) - } - - // MARK: - Get Object - - internal func getImageForKey(_ key: String, completion: @escaping (_ image: UIImage?) -> ()) { - - let callCompletionClosureOnMain = { (image: UIImage?) in - DispatchQueue.main.async { - completion(image) - } - } - - if let memoryImage = memoryCache.object(forKey: key as NSString) { - let path = getFilePathFromKey(key) - readWriteQueue.async { - self.updateDiskImageModifiedDate(path) - } - callCompletionClosureOnMain(memoryImage) - } - else { - readWriteQueue.async { - if let diskImage = self.getImageFromDiskForKey(key) { - callCompletionClosureOnMain(diskImage) - self.cacheImage(diskImage, data: nil, key: key, includingDisk: false, completion: nil) - } - else { - callCompletionClosureOnMain(nil) - } - } - } - } - - // MARK: - Set Object - - internal func cacheImage(_ image: UIImage, data: Data?, key: String, completion: (() -> ())?) { - cacheImage(image, data: data, key: key, includingDisk: true, completion: completion) - } - - func costFor(image: UIImage) -> Int { - if let imageRef = image.cgImage { - return imageRef.bytesPerRow * imageRef.height - } - - // Without the underlying cgImage we can only estimate, assuming 4 bytes per pixel (RGBA): - return Int(image.size.height * image.scale * image.size.width * image.scale) * Defines.defaultBytesPerPixel - } - - fileprivate func cacheImage(_ image: UIImage, data: Data?, key: String, includingDisk: Bool, completion: (() -> ())?) { - - if cachePolicy == .memory || cachePolicy == .disk { - let cost = costFor(image: image) - memoryCache.setObject(image, forKey: key as NSString, cost: cost) - } - - if cachePolicy == .disk && includingDisk { - let path = getFilePathFromKey(key) - readWriteQueue.async { - // If the original data was passed, save the data to the disk, otherwise default to UIImagePNGRepresentation to create the data from the image - if let data = data ?? image.pngData() { - // create the cach directory if it doesn't exist - if !FileManager.default.fileExists(atPath: self.diskCacheDir) { - do { - try FileManager.default.createDirectory(atPath: self.diskCacheDir, withIntermediateDirectories: true, attributes: nil) - } catch { - printLog(.warning, text: "Failed while attempting to create the image cache directory.") - } - } - - FileManager.default.createFile(atPath: path, contents: data, attributes: nil) - self.usedCacheSize += UInt64(data.count) - self.clearDiskToMatchCapacityIfNeeded() - } - else { - printLog(.warning, text: "Couldn't convert image to data for key: \(key)") - } - completion?() - } - } - else { - completion?() - } - } - - // MARK: - Remove Object - - internal func removeCacheImageForKey(_ key: String) { - memoryCache.removeObject(forKey: key as NSString) - let path = getFilePathFromKey(key) - removeFileAtPath(path) - } - - fileprivate func removeFileAtPath(_ path: String) { - readWriteQueue.async { - if let fileAttr = self.getFileAttributes(path) { - let fileSize = fileAttr.fileSize() - do { - try FileManager.default.removeItem(atPath: path) - self.usedCacheSize = self.usedCacheSize > fileSize ? self.usedCacheSize - fileSize : 0 - } catch { - printLog(.warning, text: "Failed while attempting to remove a cached file") - } - } - } - } - - // MARK: - Clear - - fileprivate func clearDiskToMatchCapacityIfNeeded() { - if usedCacheSize < maxDiskCapacity { - return - } - - if let sortedUrls = sortedDiskImagesByModifiedDate() { - for url in sortedUrls { - removeFileAtPath(url.path) - if usedCacheSize <= UInt64(maxDiskCapacity * Defines.thresholdPercentSize) { - break - } - } - } - } - - @objc fileprivate func clearMemoryCache() { - memoryCache.removeAllObjects() - } - - // MARK: - State - - internal func hasCachedImageForKey(_ key: String) -> Bool { - var hasCachedImage = false - if memoryCache.object(forKey: key as NSString) != nil { - hasCachedImage = true - } - else { - let imagePath = getFilePathFromKey(key) - hasCachedImage = hasCachedDiskImageAtPath(imagePath) - } - - return hasCachedImage - } - - fileprivate func hasCachedDiskImageAtPath(_ path: String) -> Bool { - var hasCachedImage = false - readWriteQueue.sync { - hasCachedImage = FileManager.default.fileExists(atPath: path) - } - return hasCachedImage - } - - // MARK: - Disk Image Helpers - - fileprivate func getImageFromDiskForKey(_ key: String) -> UIImage? { - if let data = getDataFromDiskForKey(key) { - return data.cldToUIImageThreadSafe() - } - return nil - } - - fileprivate func getDataFromDiskForKey(_ key: String) -> Data? { - let imagePath = getFilePathFromKey(key) - updateDiskImageModifiedDate(imagePath) - return (try? Data(contentsOf: URL(fileURLWithPath: imagePath))) - } - - fileprivate func getFilePathFromKey(_ key: String) -> String { - let fileName = getFileNameFromKey(key) - return diskCacheDir.cldStringByAppendingPathComponent(str: fileName) - } - - fileprivate func getFileNameFromKey(_ key: String) -> String { - return key.sha256_base64() - } - - fileprivate func updateDiskImageModifiedDate(_ path: String) { - do { - try FileManager.default.setAttributes([FileAttributeKey.modificationDate : Date()], ofItemAtPath: path) - } catch { - printLog(.warning, text: "Failed attempting to update cached file modified date.") - } - } - - // MARK: - Disk Capacity Helpers - - fileprivate func calculateCurrentDiskCacheSize() { - let fileManager = FileManager.default - usedCacheSize = 0 - do { - let contents = try fileManager.contentsOfDirectory(atPath: diskCacheDir) - for pathComponent in contents { - let filePath = diskCacheDir.cldStringByAppendingPathComponent(str: pathComponent) - if let fileAttr = getFileAttributes(filePath) { - usedCacheSize += fileAttr.fileSize() - } - } - - } catch { - printLog(.warning, text: "Failed listing cache directory") - } - } - - fileprivate func sortedDiskImagesByModifiedDate() -> [URL]? { - let dirUrl = URL(fileURLWithPath: diskCacheDir) - do { - let urlArray = try FileManager.default.contentsOfDirectory(at: dirUrl, includingPropertiesForKeys: [URLResourceKey.contentModificationDateKey], options:.skipsHiddenFiles) - - return urlArray.map { url -> (URL, TimeInterval) in - var lastModified : AnyObject? - _ = try? (url as NSURL).getResourceValue(&lastModified, forKey: URLResourceKey.contentModificationDateKey) - return (url, lastModified?.timeIntervalSinceReferenceDate ?? 0) - } - .sorted(by: { $0.1 > $1.1 }) // sort descending modification dates - .map { $0.0 } - } catch { - printLog(.warning, text: "Failed listing cache directory") - return nil - } - } - - fileprivate func getFileAttributes(_ path: String) -> NSDictionary? { - var fileAttr: NSDictionary? - do { - fileAttr = try FileManager.default.attributesOfItem(atPath: path) as NSDictionary - } catch { - printLog(.warning, text: "Failed while attempting to retrive a cached file attributes for filr at path: \(path)") - } - return fileAttr - } - -} diff --git a/Cloudinary/Classes/ios/Extensions/ExtensionCLDDownloader.swift b/Cloudinary/Classes/ios/Extensions/ExtensionCLDDownloader.swift index 3eb211fc..e002cb44 100644 --- a/Cloudinary/Classes/ios/Extensions/ExtensionCLDDownloader.swift +++ b/Cloudinary/Classes/ios/Extensions/ExtensionCLDDownloader.swift @@ -30,7 +30,7 @@ extension CLDDownloader /** Asynchronously fetches a remote image from the specified URL. The image is retrieved from the cache if it exists, otherwise its downloaded and cached. - + //TODO: REMOVE!!! - parameter url: The image URL to download. - parameter progress: The closure that is called periodically during the data transfer. - parameter completionHandler: The closure to be called once the request has finished, holding either the retrieved UIImage or the error. diff --git a/Cloudinary/Classes/ios/NetworkRequest/CLDFetchImageRequestImpl.swift b/Cloudinary/Classes/ios/NetworkRequest/CLDFetchImageRequestImpl.swift index c474e2d7..5b7c3648 100644 --- a/Cloudinary/Classes/ios/NetworkRequest/CLDFetchImageRequestImpl.swift +++ b/Cloudinary/Classes/ios/NetworkRequest/CLDFetchImageRequestImpl.swift @@ -56,20 +56,7 @@ internal class CLDFetchImageRequestImpl: CLDFetchImageRequest { func fetchImage() { DispatchQueue.global(qos: DispatchQoS.QoSClass.default).async { - if self.downloadCoordinator.imageCache.hasCachedImageForKey(self.url) { - self.downloadCoordinator.imageCache.getImageForKey(self.url, completion: { [weak self] (image) -> () in - if let fetchedImage = image { - self?.image = fetchedImage - self?.closureQueue.isSuspended = false - } - else { - self?.downloadImageAndCacheIt() - } - }) - } - else { - self.downloadImageAndCacheIt() - } + self.downloadImageAndCacheIt() } } @@ -79,23 +66,11 @@ internal class CLDFetchImageRequestImpl: CLDFetchImageRequest { imageDownloadRequest?.progress(progress) imageDownloadRequest?.responseData { [weak self] (responseData, responseError, httpCode) -> () in - if let data = responseData, !data.isEmpty { - if let - image = data.cldToUIImageThreadSafe(), - let url = self?.url { - self?.image = image - if self?.downloadCoordinator.imageCache.cachePolicy != CLDImageCachePolicy.none { - self?.downloadCoordinator.imageCache.cacheImage(image, data: data, key: url, completion: nil) - } else { - self?.downloadCoordinator.imageCache.maxDiskCapacity = 0 // Description: https://github.com/cloudinary/cloudinary_ios/pull/402 - } - } - else { - let error = CLDError.error(code: .failedCreatingImageFromData, message: "Failed creating an image from the received data.", userInfo: ["statusCode": httpCode]) - self?.error = error - } - } - else if let err = responseError { + if let data = responseData, let + image = data.cldToUIImageThreadSafe(), + let url = self?.url { + self?.image = image + } else if let err = responseError { self?.error = err } else { diff --git a/Example/Cloudinary.xcodeproj/project.pbxproj b/Example/Cloudinary.xcodeproj/project.pbxproj index ba5f514b..d442646c 100644 --- a/Example/Cloudinary.xcodeproj/project.pbxproj +++ b/Example/Cloudinary.xcodeproj/project.pbxproj @@ -184,22 +184,6 @@ D7519FAC25E2693A006839B1 /* CLDCloudinaryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7519FAA25E2693A006839B1 /* CLDCloudinaryTests.swift */; }; D7519FAD25E2693A006839B1 /* CLDCloudinaryTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D7519FAB25E2693A006839B1 /* CLDCloudinaryTests.m */; }; D7519FEC25E26BE9006839B1 /* DownloaderAssetTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7519FEB25E26BE9006839B1 /* DownloaderAssetTests.swift */; }; - D751A01625E26D83006839B1 /* CLDURLCacheConfigurationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D751A01425E26D83006839B1 /* CLDURLCacheConfigurationTests.swift */; }; - D751A01725E26D83006839B1 /* CLDURLCacheTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D751A01525E26D83006839B1 /* CLDURLCacheTests.swift */; }; - D751A03325E26DB0006839B1 /* StorehouseAccessorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D751A02025E26DB0006839B1 /* StorehouseAccessorTests.swift */; }; - D751A03425E26DB0006839B1 /* BaseStorehouseAnyTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D751A02125E26DB0006839B1 /* BaseStorehouseAnyTests.swift */; }; - D751A03525E26DB0006839B1 /* StorehouseTransformerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D751A02325E26DB0006839B1 /* StorehouseTransformerTests.swift */; }; - D751A03625E26DB0006839B1 /* StorehouseEntryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D751A02425E26DB0006839B1 /* StorehouseEntryTests.swift */; }; - D751A03725E26DB0006839B1 /* StorehouseExpiryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D751A02525E26DB0006839B1 /* StorehouseExpiryTests.swift */; }; - D751A03825E26DB0006839B1 /* WarehouseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D751A02725E26DB0006839B1 /* WarehouseTests.swift */; }; - D751A03925E26DB0006839B1 /* WarehouseTransformerFactoryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D751A02825E26DB0006839B1 /* WarehouseTransformerFactoryTests.swift */; }; - D751A03A25E26DB0006839B1 /* StorehouseHybridTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D751A02A25E26DB0006839B1 /* StorehouseHybridTests.swift */; }; - D751A03B25E26DB0006839B1 /* StorehouseAutoPurgingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D751A02C25E26DB0006839B1 /* StorehouseAutoPurgingTests.swift */; }; - D751A03C25E26DB0006839B1 /* StorehouseOnDiskTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D751A02D25E26DB0006839B1 /* StorehouseOnDiskTests.swift */; }; - D751A03D25E26DB0006839B1 /* StorehouseInMemoryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D751A02E25E26DB0006839B1 /* StorehouseInMemoryTests.swift */; }; - D751A03E25E26DB0006839B1 /* StorehouseConfigurationDiskTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D751A03025E26DB0006839B1 /* StorehouseConfigurationDiskTests.swift */; }; - D751A03F25E26DB0006839B1 /* StorehouseConfigurationAutoPurgingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D751A03125E26DB0006839B1 /* StorehouseConfigurationAutoPurgingTests.swift */; }; - D751A04025E26DB0006839B1 /* StorehouseConfigurationInMemoryTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D751A03225E26DB0006839B1 /* StorehouseConfigurationInMemoryTests.swift */; }; D7567064255D661F005B65D3 /* UploaderWidgetViewControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7567063255D661F005B65D3 /* UploaderWidgetViewControllerTests.swift */; }; D7788A3824DC482C00B63EB7 /* borderCollieCropped.jpg in Resources */ = {isa = PBXBuildFile; fileRef = D7788A3724DC482C00B63EB7 /* borderCollieCropped.jpg */; }; D7788A9424E29BEC00B63EB7 /* borderCollieRotatedJpg.jpg in Resources */ = {isa = PBXBuildFile; fileRef = D7788A9224E29BEC00B63EB7 /* borderCollieRotatedJpg.jpg */; }; @@ -432,22 +416,6 @@ D7519FAA25E2693A006839B1 /* CLDCloudinaryTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CLDCloudinaryTests.swift; sourceTree = ""; }; D7519FAB25E2693A006839B1 /* CLDCloudinaryTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CLDCloudinaryTests.m; sourceTree = ""; }; D7519FEB25E26BE9006839B1 /* DownloaderAssetTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DownloaderAssetTests.swift; sourceTree = ""; }; - D751A01425E26D83006839B1 /* CLDURLCacheConfigurationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CLDURLCacheConfigurationTests.swift; sourceTree = ""; }; - D751A01525E26D83006839B1 /* CLDURLCacheTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CLDURLCacheTests.swift; sourceTree = ""; }; - D751A02025E26DB0006839B1 /* StorehouseAccessorTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StorehouseAccessorTests.swift; sourceTree = ""; }; - D751A02125E26DB0006839B1 /* BaseStorehouseAnyTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseStorehouseAnyTests.swift; sourceTree = ""; }; - D751A02325E26DB0006839B1 /* StorehouseTransformerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StorehouseTransformerTests.swift; sourceTree = ""; }; - D751A02425E26DB0006839B1 /* StorehouseEntryTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StorehouseEntryTests.swift; sourceTree = ""; }; - D751A02525E26DB0006839B1 /* StorehouseExpiryTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StorehouseExpiryTests.swift; sourceTree = ""; }; - D751A02725E26DB0006839B1 /* WarehouseTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WarehouseTests.swift; sourceTree = ""; }; - D751A02825E26DB0006839B1 /* WarehouseTransformerFactoryTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WarehouseTransformerFactoryTests.swift; sourceTree = ""; }; - D751A02A25E26DB0006839B1 /* StorehouseHybridTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StorehouseHybridTests.swift; sourceTree = ""; }; - D751A02C25E26DB0006839B1 /* StorehouseAutoPurgingTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StorehouseAutoPurgingTests.swift; sourceTree = ""; }; - D751A02D25E26DB0006839B1 /* StorehouseOnDiskTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StorehouseOnDiskTests.swift; sourceTree = ""; }; - D751A02E25E26DB0006839B1 /* StorehouseInMemoryTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StorehouseInMemoryTests.swift; sourceTree = ""; }; - D751A03025E26DB0006839B1 /* StorehouseConfigurationDiskTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StorehouseConfigurationDiskTests.swift; sourceTree = ""; }; - D751A03125E26DB0006839B1 /* StorehouseConfigurationAutoPurgingTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StorehouseConfigurationAutoPurgingTests.swift; sourceTree = ""; }; - D751A03225E26DB0006839B1 /* StorehouseConfigurationInMemoryTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StorehouseConfigurationInMemoryTests.swift; sourceTree = ""; }; D7567063255D661F005B65D3 /* UploaderWidgetViewControllerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UploaderWidgetViewControllerTests.swift; sourceTree = ""; }; D7788A3724DC482C00B63EB7 /* borderCollieCropped.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = borderCollieCropped.jpg; sourceTree = ""; }; D7788A9224E29BEC00B63EB7 /* borderCollieRotatedJpg.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = borderCollieRotatedJpg.jpg; sourceTree = ""; }; @@ -1330,90 +1298,10 @@ D751A01225E26D5D006839B1 /* CLDURLCacheTests */ = { isa = PBXGroup; children = ( - D751A01325E26D83006839B1 /* CLDURLCache */, - D751A01E25E26D9C006839B1 /* StorehouseLibraryTests */, ); path = CLDURLCacheTests; sourceTree = ""; }; - D751A01325E26D83006839B1 /* CLDURLCache */ = { - isa = PBXGroup; - children = ( - D751A01425E26D83006839B1 /* CLDURLCacheConfigurationTests.swift */, - D751A01525E26D83006839B1 /* CLDURLCacheTests.swift */, - ); - path = CLDURLCache; - sourceTree = ""; - }; - D751A01E25E26D9C006839B1 /* StorehouseLibraryTests */ = { - isa = PBXGroup; - children = ( - D751A02125E26DB0006839B1 /* BaseStorehouseAnyTests.swift */, - D751A01F25E26DB0006839B1 /* StorehouseAccessor */, - D751A02B25E26DB0006839B1 /* StorehouseAnyTypeTests */, - D751A02F25E26DB0006839B1 /* StorehouseConfigurationTests */, - D751A02225E26DB0006839B1 /* StorehouseContentTests */, - D751A02925E26DB0006839B1 /* StorehouseHybridTests */, - D751A02625E26DB0006839B1 /* WarehouseTests */, - ); - path = StorehouseLibraryTests; - sourceTree = ""; - }; - D751A01F25E26DB0006839B1 /* StorehouseAccessor */ = { - isa = PBXGroup; - children = ( - D751A02025E26DB0006839B1 /* StorehouseAccessorTests.swift */, - ); - path = StorehouseAccessor; - sourceTree = ""; - }; - D751A02225E26DB0006839B1 /* StorehouseContentTests */ = { - isa = PBXGroup; - children = ( - D751A02325E26DB0006839B1 /* StorehouseTransformerTests.swift */, - D751A02425E26DB0006839B1 /* StorehouseEntryTests.swift */, - D751A02525E26DB0006839B1 /* StorehouseExpiryTests.swift */, - ); - path = StorehouseContentTests; - sourceTree = ""; - }; - D751A02625E26DB0006839B1 /* WarehouseTests */ = { - isa = PBXGroup; - children = ( - D751A02725E26DB0006839B1 /* WarehouseTests.swift */, - D751A02825E26DB0006839B1 /* WarehouseTransformerFactoryTests.swift */, - ); - path = WarehouseTests; - sourceTree = ""; - }; - D751A02925E26DB0006839B1 /* StorehouseHybridTests */ = { - isa = PBXGroup; - children = ( - D751A02A25E26DB0006839B1 /* StorehouseHybridTests.swift */, - ); - path = StorehouseHybridTests; - sourceTree = ""; - }; - D751A02B25E26DB0006839B1 /* StorehouseAnyTypeTests */ = { - isa = PBXGroup; - children = ( - D751A02C25E26DB0006839B1 /* StorehouseAutoPurgingTests.swift */, - D751A02D25E26DB0006839B1 /* StorehouseOnDiskTests.swift */, - D751A02E25E26DB0006839B1 /* StorehouseInMemoryTests.swift */, - ); - path = StorehouseAnyTypeTests; - sourceTree = ""; - }; - D751A02F25E26DB0006839B1 /* StorehouseConfigurationTests */ = { - isa = PBXGroup; - children = ( - D751A03025E26DB0006839B1 /* StorehouseConfigurationDiskTests.swift */, - D751A03125E26DB0006839B1 /* StorehouseConfigurationAutoPurgingTests.swift */, - D751A03225E26DB0006839B1 /* StorehouseConfigurationInMemoryTests.swift */, - ); - path = StorehouseConfigurationTests; - sourceTree = ""; - }; D779B69324B7117200E496EB /* AccessibilityUploderTests */ = { isa = PBXGroup; children = ( @@ -1843,8 +1731,6 @@ 274C6D2D23FBAF5E0090BC40 /* CryptoUtilsTests.swift in Sources */, D7E79DCC24B515260082288A /* UploaderMockOcrTests.m in Sources */, D79AE39C24585533004F2439 /* CLDVariableTests.m in Sources */, - D751A03A25E26DB0006839B1 /* StorehouseHybridTests.swift in Sources */, - D751A01725E26D83006839B1 /* CLDURLCacheTests.swift in Sources */, D7F34F9125120E0D00C282B1 /* UploaderWidgetEditViewControllerTests.swift in Sources */, D7519FEC25E26BE9006839B1 /* DownloaderAssetTests.swift in Sources */, D71B790024680773004AA28E /* CLDTransformationExpressionsTests.swift in Sources */, @@ -1855,7 +1741,6 @@ D7289C8A258A9E18004DBD29 /* UploaderWidgetVideoViewTests.swift in Sources */, 272C5180242B6C360093AB1B /* FileManager+CloudinaryTests.swift in Sources */, D71ADD9C247D976500235AD4 /* CryptoUtilsTests.m in Sources */, - D751A01625E26D83006839B1 /* CLDURLCacheConfigurationTests.swift in Sources */, 272C5187242B6C360093AB1B /* URLProtocolTests.swift in Sources */, 272C517F242B6C360093AB1B /* SessionManagerTests.swift in Sources */, 274C6D3823FBAF5E0090BC40 /* DownloaderTests.swift in Sources */, @@ -1864,14 +1749,11 @@ 274C6D3723FBAF5E0090BC40 /* ManagementApiTests.swift in Sources */, D7EF05B0255D8C1900F93827 /* UploaderWidgetTests.swift in Sources */, D7119CE3246C7C8100F6B3ED /* CLDConditionExpressionHelpersTests.swift in Sources */, - D751A03B25E26DB0006839B1 /* StorehouseAutoPurgingTests.swift in Sources */, D7289C88258A9E18004DBD29 /* UploaderWidgetVideoPlayerTests.swift in Sources */, 274C6D3123FBAF5E0090BC40 /* UrlTests.swift in Sources */, B694AAF52B308C5A00075041 /* VideoEventsManagerTests.swift in Sources */, - D751A03C25E26DB0006839B1 /* StorehouseOnDiskTests.swift in Sources */, D7567064255D661F005B65D3 /* UploaderWidgetViewControllerTests.swift in Sources */, D7F34F2F2504F48C00C282B1 /* UploaderWidgetCollectionCellTests.swift in Sources */, - D751A03525E26DB0006839B1 /* StorehouseTransformerTests.swift in Sources */, D79AE387244DF1E7004F2439 /* CLDVariableTests.swift in Sources */, 1E635A8025A7585E0003E9D3 /* ObjcUploaderQualityAnalysisTests.m in Sources */, 272C5181242B6C360093AB1B /* AuthenticationTests.swift in Sources */, @@ -1882,14 +1764,10 @@ 5D53A9512488CE23005C14AB /* CLDConfigurationTests.swift in Sources */, D779B69724B7117300E496EB /* UploaderAccessibilityTests.swift in Sources */, 27BC1FB02431C48D000AFC2C /* CLDNResult+CloudinaryTests.swift in Sources */, - D751A03825E26DB0006839B1 /* WarehouseTests.swift in Sources */, B6F11F3D288FC20900A895CD /* CLDAnalyticsTests.swift in Sources */, - D751A03625E26DB0006839B1 /* StorehouseEntryTests.swift in Sources */, 1E635A7F25A7585E0003E9D3 /* MockProviderQualityAnalysis.swift in Sources */, D73117582473D7A30051AAFC /* CLDExpressionTests.m in Sources */, 1E635A8325A7585E0003E9D3 /* UploaderQualityAnalysisTests.swift in Sources */, - D751A03925E26DB0006839B1 /* WarehouseTransformerFactoryTests.swift in Sources */, - D751A03D25E26DB0006839B1 /* StorehouseInMemoryTests.swift in Sources */, 1E635A3E25A756870003E9D3 /* ObjcBaseTestCase.m in Sources */, 274C6D3323FBAF5E0090BC40 /* UIButtonTests.swift in Sources */, 274C6D3223FBAF5E0090BC40 /* UIBaseTest.swift in Sources */, @@ -1901,7 +1779,6 @@ 274C6D3423FBAF5E0090BC40 /* UIImageViewTests.swift in Sources */, D7289C81258A9D0B004DBD29 /* UploaderWidgetAssetContainerTests.swift in Sources */, D731175A247415340051AAFC /* CLDConditionExpressionTests.m in Sources */, - D751A04025E26DB0006839B1 /* StorehouseConfigurationInMemoryTests.swift in Sources */, 272C51B5242B6C360093AB1B /* ParameterEncodingTests.swift in Sources */, 274C6D2F23FBAF5E0090BC40 /* FileUtilsTests.swift in Sources */, D7E79DCA24B515260082288A /* OcrMockProvider.swift in Sources */, @@ -1909,7 +1786,6 @@ D79AE385244CC1D7004F2439 /* CLDTransformationTests.swift in Sources */, 5DE4EC202469919A00F6C8D6 /* CLDTransformationBaselineTests.swift in Sources */, D7289C89258A9E18004DBD29 /* UploaderWidgetVideoDisplayLinkTests.swift in Sources */, - D751A03E25E26DB0006839B1 /* StorehouseConfigurationDiskTests.swift in Sources */, 27BC1FAE2431C3F6000AFC2C /* CLDNDataResponse+CloudinaryTests.swift in Sources */, D7F34F3325052FE700C282B1 /* WidgetBaseTest.swift in Sources */, B694AAF32B308C3C00075041 /* VideoEventsTests.swift in Sources */, @@ -1922,21 +1798,17 @@ D7289C87258A9E18004DBD29 /* UploaderWidgetVideoControlsTests.swift in Sources */, 272C5185242B6C360093AB1B /* ResponseSerializationTests.swift in Sources */, 272C5183242B6C360093AB1B /* SessionDelegateTests.swift in Sources */, - D751A03325E26DB0006839B1 /* StorehouseAccessorTests.swift in Sources */, 1E635A8225A7585E0003E9D3 /* ObjcQualityAnalysisExplicitResultParserTests.m in Sources */, 5D53A9522488CE23005C14AB /* CLDConfigurationTests.m in Sources */, D7E79DCB24B515260082288A /* ExplicitMockOcrTests.m in Sources */, D71B7902246808EE004AA28E /* CLDTransformationConditionsTests.swift in Sources */, - D751A03725E26DB0006839B1 /* StorehouseExpiryTests.swift in Sources */, 274C6D3623FBAF5E0090BC40 /* UploaderTests.swift in Sources */, D7E79DCD24B515260082288A /* UploaderMockOcrTests.swift in Sources */, 272C51B1242B6C360093AB1B /* CacheTests.swift in Sources */, 274C6D3023FBAF5E0090BC40 /* UrlTests.m in Sources */, 272C518C242B6C360093AB1B /* BaseTestCase.swift in Sources */, 5D4D8C2E24609C1400AE9C96 /* ValidationTests.swift in Sources */, - D751A03425E26DB0006839B1 /* BaseStorehouseAnyTests.swift in Sources */, 272C51B4242B6C360093AB1B /* ResultTests.swift in Sources */, - D751A03F25E26DB0006839B1 /* StorehouseConfigurationAutoPurgingTests.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Example/Tests/BaseNetwork/Core/CLDCloudinaryTests.swift b/Example/Tests/BaseNetwork/Core/CLDCloudinaryTests.swift index 52c4b2c2..230fedaa 100644 --- a/Example/Tests/BaseNetwork/Core/CLDCloudinaryTests.swift +++ b/Example/Tests/BaseNetwork/Core/CLDCloudinaryTests.swift @@ -127,22 +127,5 @@ class CLDCloudinaryTests: XCTestCase { XCTAssertNotNil(tempSut, "initialized object should not be nil") XCTAssertEqual (tempSut.config, tempConfiguration, "Initilized object should contain expected value") } - - // MARK: - default values - func test_init_defaultVaues_shouldBeEqualToExpectedValues() { - - // Given - let defaultCachePolicy : CLDImageCachePolicy = .none - let defaultUrlCachePolicy : Bool = true - let defaultCacheMaxDiskCapacity : UInt64 = 150 * 1024 * 1024 - let defaultCacheMaxMemoryTotalCost: Int = 30 * 1024 * 1024 - - // Then - XCTAssertNotNil(sut, "initialized object should not be nil") - XCTAssertEqual (sut.config, config, "Initilized object should contain expected value") - XCTAssertEqual (sut.cachePolicy, defaultCachePolicy, "Initilized object should contain expected value") - XCTAssertEqual(sut.enableUrlCache, defaultUrlCachePolicy) - XCTAssertEqual (sut.cacheMaxDiskCapacity, defaultCacheMaxDiskCapacity, "Initilized object should contain expected value") - XCTAssertEqual (sut.cacheMaxMemoryTotalCost, defaultCacheMaxMemoryTotalCost, "Initilized object should contain expected value") - } + } diff --git a/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/CLDURLCache/CLDURLCacheConfigurationTests.swift b/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/CLDURLCache/CLDURLCacheConfigurationTests.swift deleted file mode 100644 index e5f9e6a8..00000000 --- a/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/CLDURLCache/CLDURLCacheConfigurationTests.swift +++ /dev/null @@ -1,67 +0,0 @@ -// -// CLDURLCacheConfigurationTests.swift -// -// Copyright (c) 2020 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -@testable import Cloudinary -import Foundation -import XCTest - -class CLDURLCacheConfigurationTests: XCTestCase { - - var sut : CLDURLCacheConfiguration! - - override func setUp() { - super.setUp() - - sut = CLDURLCacheConfiguration.defualt - } - - override func tearDownWithError() throws { - sut = nil - super.tearDown() - } - - // MARK: - init - func test_init_currentDefaultParamaters_shouldStoreDefaultProperties() { - - // Given - let securedStorage = false - let minCacheResponseAge = TimeInterval(259200) - let maxCacheResponseAge = TimeInterval(604800) - let expirationDelayDefault = TimeInterval(1 * 60 * 60) // 1 hours - let expirationDelayMinimum = TimeInterval(5 * 60 ) // 5 minutes - let lastModificationFraction = Double(0.1) - let logingScope = CLDURLCacheConfiguration.LogingScope.debugOnly - - // Then - XCTAssertNotNil(sut, "Initilized object should not be nil") - XCTAssertEqual(sut.securedStorage, securedStorage, "Initilized object should contain expected value") - XCTAssertEqual(sut.minCacheResponseAge, minCacheResponseAge, "Initilized object should contain expected value") - XCTAssertEqual(sut.maxCacheResponseAge, maxCacheResponseAge, "Initilized object should contain expected value") - XCTAssertEqual(sut.expirationDelayDefault, expirationDelayDefault, "Initilized object should contain expected value") - XCTAssertEqual(sut.expirationDelayMinimum, expirationDelayMinimum, "Initilized object should contain expected value") - XCTAssertEqual(sut.lastModificationFraction, lastModificationFraction, "Initilized object should contain expected value") - XCTAssertEqual(sut.logingScope, logingScope, "Initilized object should contain expected value") - } - -} diff --git a/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/CLDURLCache/CLDURLCacheTests.swift b/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/CLDURLCache/CLDURLCacheTests.swift deleted file mode 100644 index 2447f414..00000000 --- a/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/CLDURLCache/CLDURLCacheTests.swift +++ /dev/null @@ -1,61 +0,0 @@ -// -// CLDURLCacheTests.swift -// -// Copyright (c) 2020 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -@testable import Cloudinary -import Foundation -import XCTest - -class CLDURLCacheTests: XCTestCase { - - var sut : CLDURLCache! - - override func setUp() { - super.setUp() - - let configuration = CLDURLCacheConfiguration.init() - sut = CLDURLCache(memoryCapacity: 1000, diskCapacity: 1000, diskPath: "", configuration: configuration) - } - - override func tearDownWithError() throws { - sut = nil - super.tearDown() - } - - // MARK: - init - func test_init_allParamaters_shouldStoreProperties() { - - // Given - let memoryCapacity : Int = 60_000_000 - let diskCapacity : Int = 100_000_000 - let path : String = "path" - let configuration = CLDURLCacheConfiguration() - - // When - sut = CLDURLCache(memoryCapacity: memoryCapacity, diskCapacity: diskCapacity, diskPath: path, configuration: configuration) - - // Then - XCTAssertEqual(sut.memoryCapacity, memoryCapacity, "Initilized object should contain expected value") - XCTAssertEqual(sut.diskCapacity, diskCapacity, "Initilized object should contain expected value") - } -} diff --git a/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/BaseStorehouseAnyTests.swift b/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/BaseStorehouseAnyTests.swift deleted file mode 100644 index e727908c..00000000 --- a/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/BaseStorehouseAnyTests.swift +++ /dev/null @@ -1,164 +0,0 @@ -// -// BaseStorehouseAnyTests.swift -// Cloudinary_Tests -// -// Created by Oz Deutsch on 13/01/2021. -// Copyright © 2021 CocoaPods. All rights reserved. -// - -@testable import Cloudinary -import Foundation -import XCTest - - -class BaseStorehouseAnyTests> : XCTestCase { - - var sut : Storehouse! - - // MARK: - funcs - func test_funcs_emptyEntry_shouldReturnNil() { - - // When - let entry = try? sut.entry(forKey: "key") - - // Then - XCTAssertNil(entry, "uninserted value should be nil") - } - func test_funcs_setObjectAndEntry_objectShouldBeSet() { - - // Given - let objectToSave = "objectToSave" - let savedObjectKey = "key" - - // When - try? sut.setObject(objectToSave, forKey: savedObjectKey) - let entry = try? sut.entry(forKey: savedObjectKey).object - - // Then - XCTAssertEqual(entry, objectToSave, "object should be set") - } - func test_funcs_removeAll_shouldReturnNil() { - - // Given - let objectToSave = "objectToSave" - let savedObjectKey = "key" - - // When - try? sut.setObject(objectToSave, forKey: savedObjectKey) - try? sut.removeAll() - - let entry = try? sut.entry(forKey: savedObjectKey).object - - // Then - XCTAssertNil(entry, "removed value should be nil") - } - func test_funcs_removeByKey_shouldReturnNil() { - - // Given - let objectToSave = "objectToSave" - let savedObjectKey = "key" - - // When - try? sut.setObject(objectToSave, forKey: savedObjectKey) - try? sut.removeObject(forKey: savedObjectKey) - - let entry = try? sut.entry(forKey: savedObjectKey).object - - // Then - XCTAssertNil(entry, "removed value should be nil") - } - func test_funcs_removeObjectIfExpired_shouldReturnNil() { - - // Given - let objectToSave = "objectToSave" - let savedObjectKey = "key" - - // When - try? sut.setObject(objectToSave, forKey: savedObjectKey) - try? sut.removeObjectIfExpired(forKey: savedObjectKey) - - let entry = try? sut.entry(forKey: savedObjectKey).object - - // Then - XCTAssertNil(entry, "removed value should be nil") - } - func test_funcs_removeExpiredObjects_shouldReturnNil() { - - // Given - let objectToSave1 = "objectToSave1" - let savedObjectKey1 = "key1" - let objectToSave2 = "objectToSave2" - let savedObjectKey2 = "key2" - - // When - try? sut.setObject(objectToSave1, forKey: savedObjectKey1) - try? sut.setObject(objectToSave2, forKey: savedObjectKey2) - try? sut.removeExpiredObjects() - - let entry1 = try? sut.entry(forKey: savedObjectKey1).object - let entry2 = try? sut.entry(forKey: savedObjectKey2).object - - // Then - XCTAssertNil(entry1, "removed value should be nil") - XCTAssertNil(entry2, "removed value should be nil") - } - func test_funcs_removeStoredObjects_shouldReturnNil() { - - // Given - let objectToSave1 = "objectToSave1" - let savedObjectKey1 = "key1" - let objectToSave2 = "objectToSave2" - let savedObjectKey2 = "key2" - - // When - try? sut.setObject(objectToSave1, forKey: savedObjectKey1) - try? sut.setObject(objectToSave2, forKey: savedObjectKey2) - try? sut.removeStoredObjects(since: Date()) - - let entry1 = try? sut.entry(forKey: savedObjectKey1).object - let entry2 = try? sut.entry(forKey: savedObjectKey2).object - - // Then - XCTAssertNil(entry1, "removed value should be nil") - XCTAssertNil(entry2, "removed value should be nil") - } - func test_funcs_Object_objectShouldBeSet() { - - // Given - let objectToSave = "objectToSave" - let savedObjectKey = "key" - - // When - try? sut.setObject(objectToSave, forKey: savedObjectKey) - let entry = try? sut.object(forKey: savedObjectKey) - - // Then - XCTAssertEqual(entry, objectToSave, "object should be set") - } - func test_funcs_exists_objectShouldExists() { - - // Given - let objectToSave = "objectToSave" - let savedObjectKey = "key" - - // When - try? sut.setObject(objectToSave, forKey: savedObjectKey) - let objectExists = try? sut.existsObject(forKey: savedObjectKey) - - // Then - XCTAssert(objectExists == true, "object should be set") - } - func test_funcs_expired_objectShouldBeExpired() { - - // Given - let objectToSave = "objectToSave" - let savedObjectKey = "key" - - // When - try? sut.setObject(objectToSave, forKey: savedObjectKey) - let objectExpired = try? sut.isExpiredObject(forKey: savedObjectKey) - - // Then - XCTAssertTrue(objectExpired == true, "object should be expired") - } -} diff --git a/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/StorehouseAccessor/StorehouseAccessorTests.swift b/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/StorehouseAccessor/StorehouseAccessorTests.swift deleted file mode 100644 index 2da5f94f..00000000 --- a/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/StorehouseAccessor/StorehouseAccessorTests.swift +++ /dev/null @@ -1,304 +0,0 @@ -// -// StorehouseAccessorTests.swift -// -// Copyright (c) 2020 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -@testable import Cloudinary -import Foundation -import XCTest - -class StorehouseAccessorTests: XCTestCase { - - var sut : StorehouseAccessor! - let maximumSizeDisk = 100_000_000 - - override func setUp() { - super.setUp() - - sut = createSut() - } - - func createSut() -> StorehouseAccessor! { - - // create storehouseOnDisk - let nameDisk : String = "nameTest" - let expiryDateDisk : Date = Date() - let expiryDisk : StorehouseExpiry = .date(expiryDateDisk) - let maxSizeDisk : Int = maximumSizeDisk - let protectionTypeDisk: FileProtectionType? = .complete - - let configuration = StorehouseConfigurationDisk(name: nameDisk , expiry: expiryDisk , maxSize: maxSizeDisk, protectionType: protectionTypeDisk) - let transformer = WarehouseTransformerFactory.forCodable(ofType: String.self) - - let storehouseOnDisk: StorehouseOnDisk = try! StorehouseOnDisk(configuration: configuration, transformer: transformer) - - // create storehouseInMemory - let expiryDateMemory : Date = Date() - let expiryMemory : StorehouseExpiry = .date(expiryDateMemory) - let countLimitMemory : UInt = 100_000_000 - let totalCostLimitMemory: UInt = 100_000_000 - let configurationMemory = StorehouseConfigurationInMemory(expiry: expiryMemory, countLimit: countLimitMemory, totalCostLimit: totalCostLimitMemory) - - let storehouseInMemory: StorehouseInMemory = StorehouseInMemory(configuration: configurationMemory) - - // create storehouseHybrid - let storehouseHybrid = StorehouseHybrid(inMemory: storehouseInMemory, onDisk: storehouseOnDisk) - let queue = DispatchQueue(label: "com.cloudinary.accessQueue", attributes: [.concurrent]) - return StorehouseAccessor(storage: storehouseHybrid, queue: queue) - } - - override func tearDownWithError() throws { - try? sut.removeAll() - sut = nil - - super.tearDown() - } - - // MARK: - init - func test_init_shouldBeInitialized() { - - // When - let tempSut = createSut() - - // Then - XCTAssertNotNil(tempSut, "sut should be initialized") - } - - // MARK: - vars - func test_vars_shouldReturnExpectedValue() { - - // Given - let expectedMemoryCapacity = NSNotFound - let expectedDiskCapacity = maximumSizeDisk - let expectedMemoryUsage = NSNotFound - let expectedDiskUsage = 25 - - let objectToSave = "objectToSave" - let savedObjectKey = "key" - - // When - try? sut.setObject(objectToSave, forKey: savedObjectKey) - - // Then - XCTAssertEqual(sut.memoryCapacity, expectedMemoryCapacity, "initialized value should be equal to expected value") - XCTAssertEqual(sut.diskCapacity, expectedDiskCapacity, "initialized value should be equal to expected value") - XCTAssertEqual(sut.currentMemoryUsage, expectedMemoryUsage, "initialized value should be equal to expected value") - XCTAssertEqual(sut.currentDiskUsage, expectedDiskUsage, "initialized value should be equal to expected value") - } - func test_vars_diskCapacity_shouldReturnExpectedValue() { - - // Given - let objectToSave1 = "objectToSave1" - let savedObjectKey1 = "key1" - let objectToSave2 = "objectToSave2" - let savedObjectKey2 = "key2" - let expectedDiskUsage = 52 - - // When - try? sut.setObject(objectToSave1, forKey: savedObjectKey1) - try? sut.setObject(objectToSave2, forKey: savedObjectKey2) - let currentDiskUsage = sut.currentDiskUsage - - // Then - XCTAssertEqual(currentDiskUsage, expectedDiskUsage, "entered strings should use expected disk space") - } - func test_vars_memoryCapacity_shouldReturnExpectedValue() { - - // Given - let objectToSave1 = "objectToSave1" - let savedObjectKey1 = "key1" - let objectToSave2 = "objectToSave2" - let savedObjectKey2 = "key2" - let expectedDiskUsage = 52 - - // When - try? sut.setObject(objectToSave1, forKey: savedObjectKey1) - try? sut.setObject(objectToSave2, forKey: savedObjectKey2) - let currentDiskUsage = sut.currentDiskUsage - - // Then - XCTAssertEqual(currentDiskUsage, expectedDiskUsage, "entered strings should use expected disk space") - } - func test_vars_currentMemoryUsage_shouldReturnExpectedValue() { - - // Given - let objectToSave1 = "objectToSave1" - let savedObjectKey1 = "key1" - let objectToSave2 = "objectToSave2" - let savedObjectKey2 = "key2" - let expectedDiskUsage = 52 - - // When - try? sut.setObject(objectToSave1, forKey: savedObjectKey1) - try? sut.setObject(objectToSave2, forKey: savedObjectKey2) - let currentDiskUsage = sut.currentDiskUsage - - // Then - XCTAssertEqual(currentDiskUsage, expectedDiskUsage, "entered strings should use expected disk space") - } - - // MARK: - funcs - func test_funcs_emptyEntry_shouldReturnNil() { - - let entry = try? sut.entry(forKey: "key") - - // Then - XCTAssertNil(entry, "uninserted value should be nil") - } - func test_funcs_setObjectAndEntry_objectShouldBeSet() { - - // Given - let objectToSave = "objectToSave" - let savedObjectKey = "key" - - // When - try? sut.setObject(objectToSave, forKey: savedObjectKey) - let entry = try? sut.entry(forKey: savedObjectKey).object - - // Then - XCTAssertEqual(entry, objectToSave, "object should be set") - } - func test_funcs_removeAll_shouldReturnNil() { - - // Given - let objectToSave = "objectToSave" - let savedObjectKey = "key" - - // When - try? sut.setObject(objectToSave, forKey: savedObjectKey) - try? sut.removeAll() - - let entry = try? sut.entry(forKey: savedObjectKey).object - - // Then - XCTAssertNil(entry, "removed value should be nil") - } - func test_funcs_removeByKey_shouldReturnNil() { - - // Given - let objectToSave = "objectToSave" - let savedObjectKey = "key" - - // When - try? sut.setObject(objectToSave, forKey: savedObjectKey) - try? sut.removeObject(forKey: savedObjectKey) - - let entry = try? sut.entry(forKey: savedObjectKey).object - - // Then - XCTAssertNil(entry, "removed value should be nil") - } - func test_funcs_removeObjectIfExpired_shouldReturnNil() { - - // Given - let objectToSave = "objectToSave" - let savedObjectKey = "key" - - // When - try? sut.setObject(objectToSave, forKey: savedObjectKey) - try? sut.removeObjectIfExpired(forKey: savedObjectKey) - - let entry = try? sut.entry(forKey: savedObjectKey).object - - // Then - XCTAssertNil(entry, "removed value should be nil") - } - func test_funcs_removeExpiredObjects_shouldReturnNil() { - - // Given - let objectToSave1 = "objectToSave1" - let savedObjectKey1 = "key1" - let objectToSave2 = "objectToSave2" - let savedObjectKey2 = "key2" - - // When - try? sut.setObject(objectToSave1, forKey: savedObjectKey1) - try? sut.setObject(objectToSave2, forKey: savedObjectKey2) - try? sut.removeExpiredObjects() - - let entry1 = try? sut.entry(forKey: savedObjectKey1).object - let entry2 = try? sut.entry(forKey: savedObjectKey2).object - - // Then - XCTAssertNil(entry1, "removed value should be nil") - XCTAssertNil(entry2, "removed value should be nil") - } - func test_funcs_removeStoredObjects_shouldReturnNil() { - - // Given - let objectToSave1 = "objectToSave1" - let savedObjectKey1 = "key1" - let objectToSave2 = "objectToSave2" - let savedObjectKey2 = "key2" - - // When - try? sut.setObject(objectToSave1, forKey: savedObjectKey1) - try? sut.setObject(objectToSave2, forKey: savedObjectKey2) - try? sut.removeStoredObjects(since: Date()) - - let entry1 = try? sut.entry(forKey: savedObjectKey1).object - let entry2 = try? sut.entry(forKey: savedObjectKey2).object - - // Then - XCTAssertNil(entry1, "removed value should be nil") - XCTAssertNil(entry2, "removed value should be nil") - } - func test_funcs_Object_objectShouldBeSet() { - - // Given - let objectToSave = "objectToSave" - let savedObjectKey = "key" - - // When - try? sut.setObject(objectToSave, forKey: savedObjectKey) - let entry = try? sut.object(forKey: savedObjectKey) - - // Then - XCTAssertEqual(entry, objectToSave, "object should be set") - } - func test_funcs_exists_objectShouldExists() { - - // Given - let objectToSave = "objectToSave" - let savedObjectKey = "key" - - // When - try? sut.setObject(objectToSave, forKey: savedObjectKey) - let objectExists = try? sut.existsObject(forKey: savedObjectKey) - - // Then - XCTAssert(objectExists == true, "object should be set") - } - func test_funcs_expired_objectShouldBeExpired() { - - // Given - let objectToSave = "objectToSave" - let savedObjectKey = "key" - - // When - try? sut.setObject(objectToSave, forKey: savedObjectKey) - let objectExpired = try? sut.isExpiredObject(forKey: savedObjectKey) - - // Then - XCTAssertTrue(objectExpired == true, "object should be expired") - } -} diff --git a/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/StorehouseAnyTypeTests/StorehouseAutoPurgingTests.swift b/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/StorehouseAnyTypeTests/StorehouseAutoPurgingTests.swift deleted file mode 100644 index 72a03be0..00000000 --- a/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/StorehouseAnyTypeTests/StorehouseAutoPurgingTests.swift +++ /dev/null @@ -1,96 +0,0 @@ -// -// StorehouseAutoPurgingTests.swift -// -// Copyright (c) 2020 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -@testable import Cloudinary -import Foundation -import XCTest - -class StorehouseAutoPurgingTests: BaseStorehouseAnyTests> { - - var expireNow: StorehouseExpiry = .date(Date()) - - override func setUp() { - super.setUp() - - createSut() - } - - func createSut() { - - let expiryDate : Date = Date() - let expiry : StorehouseExpiry = .date(expiryDate) - let memory : Int = 100_000_000 - let afterPurge : Int = 60_000_000 - - let configuration = StorehouseConfigurationAutoPurging(expiry: expiry, memory: memory, preferredMemoryUsageAfterPurge: afterPurge) - let transformer = WarehouseTransformerFactory.forCodable(ofType: String.self) - - sut = StorehouseAutoPurging(configuration: configuration, transformer: transformer) - } - - override func tearDownWithError() throws { - try? sut.removeAll() - sut = nil - - super.tearDown() - } - - // MARK: - init - func test_init_shouldStoreDefaultProperties() { - - // Given - let expiryDate : Date = Date() - let expiry : StorehouseExpiry = .date(expiryDate) - let memory : Int = 100_000_000 - let afterPurge : Int = 60_000_000 - - let configuration = StorehouseConfigurationAutoPurging(expiry: expiry, memory: memory, preferredMemoryUsageAfterPurge: afterPurge) - let transformer = WarehouseTransformerFactory.forCodable(ofType: String.self) - - let uninitializedSut = StorehouseAutoPurging(configuration: configuration, transformer: transformer) - - // Then - XCTAssertEqual(uninitializedSut.memoryCapacity, memory, "initialized value should be equal to expected value") - XCTAssertEqual(uninitializedSut.preferredMemoryUsageAfterPurge, afterPurge, "initialized value should be equal to expected value") - } - - // MARK: - vars - func test_vars_currentDiskUsage_shouldReturnExpectedValue() { - - // Given - let objectToSave1 = "objectToSave1" - let savedObjectKey1 = "key1" - let objectToSave2 = "objectToSave2" - let savedObjectKey2 = "key2" - let expectedMemoryUsage = 52 - - // When - try? sut.setObject(objectToSave1, forKey: savedObjectKey1, expiry: expireNow) - try? sut.setObject(objectToSave2, forKey: savedObjectKey2, expiry: expireNow) - let currentMemoryUsage = sut.currentMemoryUsage - - // Then - XCTAssertEqual(currentMemoryUsage, expectedMemoryUsage, "entered strings should use expected disk space") - } -} diff --git a/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/StorehouseAnyTypeTests/StorehouseInMemoryTests.swift b/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/StorehouseAnyTypeTests/StorehouseInMemoryTests.swift deleted file mode 100644 index fbad23ac..00000000 --- a/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/StorehouseAnyTypeTests/StorehouseInMemoryTests.swift +++ /dev/null @@ -1,75 +0,0 @@ -// -// StorehouseInMemoryTests.swift -// -// Copyright (c) 2020 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -@testable import Cloudinary -import Foundation -import XCTest - -class StorehouseInMemoryTests: BaseStorehouseAnyTests> { - - override func setUp() { - super.setUp() - - createSut() - } - - func createSut() { - - let expiryDate : Date = Date() - let expiry : StorehouseExpiry = .date(expiryDate) - let countLimit : UInt = 100_000_000 - let totalCostLimit: UInt = 100_000_000 - let configuration = StorehouseConfigurationInMemory(expiry: expiry, countLimit: countLimit, totalCostLimit: totalCostLimit) - - sut = StorehouseInMemory(configuration: configuration) - } - - override func tearDownWithError() throws { - try? sut.removeAll() - sut = nil - - super.tearDown() - } - - // MARK: - init - func test_init_shouldStoreDefaultProperties() { - - // Given - let defaultMemoryCapacity = NSNotFound - let defaultCurrentMemoryUsage = NSNotFound - - let expiryDate : Date = Date() - let expiry : StorehouseExpiry = .date(expiryDate) - let countLimit : UInt = 9 - let totalCostLimit: UInt = 11 - let configuration = StorehouseConfigurationInMemory(expiry: expiry, countLimit: countLimit, totalCostLimit: totalCostLimit) - - // When - let uninitializedSut: StorehouseInMemory = StorehouseInMemory(configuration: configuration) - - // Then - XCTAssertEqual(uninitializedSut.memoryCapacity, defaultMemoryCapacity, "default value should be equal to expected value") - XCTAssertEqual(uninitializedSut.currentMemoryUsage, defaultCurrentMemoryUsage, "default value should be equal to expected value") - } -} diff --git a/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/StorehouseAnyTypeTests/StorehouseOnDiskTests.swift b/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/StorehouseAnyTypeTests/StorehouseOnDiskTests.swift deleted file mode 100644 index 25c4cc44..00000000 --- a/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/StorehouseAnyTypeTests/StorehouseOnDiskTests.swift +++ /dev/null @@ -1,97 +0,0 @@ -// -// StorehouseOnDiskTests.swift -// -// Copyright (c) 2020 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -@testable import Cloudinary -import Foundation -import XCTest - -class StorehouseOnDiskTests: BaseStorehouseAnyTests> { - - override func setUp() { - super.setUp() - - createSut() - } - - func createSut() { - - let name : String = "nameTest" - let expiryDate : Date = Date() - let expiry : StorehouseExpiry = .date(expiryDate) - let maxSize : Int = 100_000_000 - let protectionType: FileProtectionType? = .complete - - let configuration = StorehouseConfigurationDisk(name: name, expiry: expiry, maxSize: maxSize, protectionType: protectionType) - let transformer = WarehouseTransformerFactory.forCodable(ofType: String.self) - - sut = try? StorehouseOnDisk(configuration: configuration, transformer: transformer) - } - - override func tearDownWithError() throws { - try? sut.removeAll() - sut = nil - - super.tearDown() - } - - // MARK: - init - func test_init_shouldStoreDefaultProperties() { - - // Given - let name : String = "nameTest" - let expiryDate : Date = Date() - let expiry : StorehouseExpiry = .date(expiryDate) - let maxSize : Int = 100_000_000 - let protectionType: FileProtectionType? = .complete - - let configuration = StorehouseConfigurationDisk(name: name, expiry: expiry, maxSize: maxSize, protectionType: protectionType) - let transformer = WarehouseTransformerFactory.forCodable(ofType: String.self) - - // When - let uninitializedSut = try? StorehouseOnDisk(configuration: configuration, transformer: transformer) - - // Then - XCTAssertEqual(uninitializedSut?.cacheContainerName, name, "initialized value should be equal to expected value") - XCTAssertEqual(uninitializedSut?.diskCapacity, maxSize, "initialized value should be equal to expected value") - } - - // MARK: - vars - func test_vars_currentDiskUsage_shouldReturnExpectedValue() { - - // Given - let objectToSave1 = "objectToSave1" - let savedObjectKey1 = "key1" - let objectToSave2 = "objectToSave2" - let savedObjectKey2 = "key2" - let expectedDiskUsage = 52 - - // When - try? sut.setObject(objectToSave1, forKey: savedObjectKey1) - try? sut.setObject(objectToSave2, forKey: savedObjectKey2) - let currentDiskUsage = sut.currentDiskUsage - - // Then - XCTAssertEqual(currentDiskUsage, expectedDiskUsage, "entered strings should use expected disk space") - } -} diff --git a/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/StorehouseConfigurationTests/StorehouseConfigurationAutoPurgingTests.swift b/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/StorehouseConfigurationTests/StorehouseConfigurationAutoPurgingTests.swift deleted file mode 100644 index 01dba17a..00000000 --- a/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/StorehouseConfigurationTests/StorehouseConfigurationAutoPurgingTests.swift +++ /dev/null @@ -1,75 +0,0 @@ -// -// StorehouseConfigurationAutoPurgingTests.swift -// -// Copyright (c) 2020 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -@testable import Cloudinary -import Foundation -import XCTest - -class StorehouseConfigurationAutoPurgingTests: XCTestCase { - - var sut : StorehouseConfigurationAutoPurging! - - override func tearDownWithError() throws { - sut = nil - super.tearDown() - } - - // MARK: - init - func test_init_allParamaters_shouldStoreProperties() { - - // Given - let expiryDate : Date = Date() - let expiry : StorehouseExpiry = .date(expiryDate) - let memory : Int = 9 - let afterPurge : Int = 11 - - // When - sut = StorehouseConfigurationAutoPurging(expiry: expiry, memory: memory, preferredMemoryUsageAfterPurge: afterPurge) - - // Then - XCTAssertEqual(sut.expiry.date, expiryDate, "Initilized object should contain expected value") - XCTAssertEqual(sut.memoryCapacity, memory, "Initilized object should contain expected value") - XCTAssertEqual(sut.preferredMemoryUsageAfterPurge, afterPurge, "Initilized object should contain expected value") - } - func test_init_emptyParamaters_shouldStoreDefaultProperties() { - - // Given - let defaultMemoryCapacity : Int = 100_000_000 - let defaultAfterPurge : Int = 60_000_000 - - // When - sut = StorehouseConfigurationAutoPurging() - - // Then - switch sut.expiry { - case .never: - break - default: - XCTFail("default expiry value should be .never") - } - - XCTAssertEqual(sut.memoryCapacity, defaultMemoryCapacity, "default value should be equal to expected value") - XCTAssertEqual(sut.preferredMemoryUsageAfterPurge, defaultAfterPurge, "default value should be equal to expected value") - } -} diff --git a/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/StorehouseConfigurationTests/StorehouseConfigurationDiskTests.swift b/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/StorehouseConfigurationTests/StorehouseConfigurationDiskTests.swift deleted file mode 100644 index 3d2fae1d..00000000 --- a/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/StorehouseConfigurationTests/StorehouseConfigurationDiskTests.swift +++ /dev/null @@ -1,79 +0,0 @@ -// -// StorehouseConfigurationDiskTests.swift -// -// Copyright (c) 2020 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -@testable import Cloudinary -import Foundation -import XCTest - -class StorehouseConfigurationDiskTests: XCTestCase { - - var sut : StorehouseConfigurationDisk! - - override func tearDownWithError() throws { - sut = nil - super.tearDown() - } - - // MARK: - init - func test_init_allParamaters_shouldStoreProperties() { - - // Given - let name : String = "testName" - let expiryDate : Date = Date() - let expiry : StorehouseExpiry = .date(expiryDate) - let maxSize : Int = 9 - let protectionType : FileProtectionType? = .complete - - // When - sut = StorehouseConfigurationDisk(name: name, expiry: expiry, maxSize: maxSize, protectionType: protectionType) - - // Then - XCTAssertEqual(sut.name, name, "Initilized object should contain expected value") - XCTAssertEqual(sut.expiry.date, expiryDate, "Initilized object should contain expected value") - XCTAssertEqual(sut.maximumSize, maxSize, "Initilized object should contain expected value") - XCTAssertEqual(sut.protectionType, protectionType, "Initilized object should contain expected value") - } - func test_init_onlyNameParamaters_shouldStoreDefaultProperties() { - - // Given - let name : String = "testName" - let defaultMaxSize : Int = 0 - let defaultProtectionType : FileProtectionType? = nil - - // When - sut = StorehouseConfigurationDisk(name: name) - - // Then - switch sut.expiry { - case .never: - break - default: - XCTFail("default expiry value should be .never") - } - - XCTAssertEqual(sut.name, name, "default value should be equal to expected value") - XCTAssertEqual(sut.maximumSize, defaultMaxSize, "default value should be equal to expected value") - XCTAssertEqual(sut.protectionType, defaultProtectionType, "default value should be equal to expected value") - } -} diff --git a/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/StorehouseConfigurationTests/StorehouseConfigurationInMemoryTests.swift b/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/StorehouseConfigurationTests/StorehouseConfigurationInMemoryTests.swift deleted file mode 100644 index 852d9069..00000000 --- a/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/StorehouseConfigurationTests/StorehouseConfigurationInMemoryTests.swift +++ /dev/null @@ -1,75 +0,0 @@ -// -// StorehouseConfigurationInMemoryTests.swift -// -// Copyright (c) 2020 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -@testable import Cloudinary -import Foundation -import XCTest - -class StorehouseConfigurationInMemoryTests: XCTestCase { - - var sut : StorehouseConfigurationInMemory! - - override func tearDownWithError() throws { - sut = nil - super.tearDown() - } - - // MARK: - init - func test_init_allParamaters_shouldStoreProperties() { - - // Given - let expiryDate : Date = Date() - let expiry : StorehouseExpiry = .date(expiryDate) - let countLimit : UInt = 9 - let totalCostLimit: UInt = 11 - - // When - sut = StorehouseConfigurationInMemory(expiry: expiry, countLimit: countLimit, totalCostLimit: totalCostLimit) - - // Then - XCTAssertEqual(sut.expiry.date, expiryDate, "Initilized object should contain expected value") - XCTAssertEqual(sut.countLimit, countLimit, "Initilized object should contain expected value") - XCTAssertEqual(sut.totalCostLimit, totalCostLimit, "Initilized object should contain expected value") - } - func test_init_emptyParamaters_shouldStoreDefaultProperties() { - - // Given - let defaultCountLimit : UInt = 0 - let defaultTotalCostLimit: UInt = 0 - - // When - sut = StorehouseConfigurationInMemory() - - // Then - switch sut.expiry { - case .never: - break - default: - XCTFail("default expiry value should be .never") - } - - XCTAssertEqual(sut.countLimit, defaultCountLimit, "default value should be equal to expected value") - XCTAssertEqual(sut.totalCostLimit, defaultTotalCostLimit, "default value should be equal to expected value") - } -} diff --git a/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/StorehouseContentTests/StorehouseEntryTests.swift b/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/StorehouseContentTests/StorehouseEntryTests.swift deleted file mode 100644 index 6dc76daa..00000000 --- a/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/StorehouseContentTests/StorehouseEntryTests.swift +++ /dev/null @@ -1,73 +0,0 @@ -// -// StorehouseEntryTests.swift -// -// Copyright (c) 2020 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -@testable import Cloudinary -import Foundation -import XCTest - -class StorehouseEntryTests: XCTestCase { - - var sut : StorehouseEntry! - - override func tearDownWithError() throws { - - sut = nil - super.tearDown() - } - - // MARK: - init - func test_init_default_shouldBeInitialized() { - - // Given - let inputObject : String = "inputObject" - let expiryDate : Date = Date() - let expiry : StorehouseExpiry = .date(expiryDate) - - // When - sut = StorehouseEntry(object: inputObject, expiry: expiry) - - // Then - XCTAssertNotNil(sut, "sut should be initialized") - XCTAssertEqual(sut.object, inputObject, "initialized value should be set") - XCTAssertEqual(sut.expiry.date, expiryDate, "initialized value should be set") - XCTAssertNil (sut.filePath, "default value should be nil") - } - func test_init_shouldBeInitialized() { - - // Given - let inputObject : String = "inputObject" - let expiryDate : Date = Date() - let expiry : StorehouseExpiry = .date(expiryDate) - let path : String = "path" - - // When - sut = StorehouseEntry(object: inputObject, expiry: expiry, filePath: path) - - // Then - XCTAssertNotNil(sut, "sut should be initialized") - XCTAssertEqual(sut.object, inputObject, "initialized value should be set") - XCTAssertEqual(sut.expiry.date, expiryDate, "initialized value should be set") - XCTAssertEqual(sut.filePath, path, "initialized value should be set") - } -} diff --git a/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/StorehouseContentTests/StorehouseExpiryTests.swift b/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/StorehouseContentTests/StorehouseExpiryTests.swift deleted file mode 100644 index c54bb6cc..00000000 --- a/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/StorehouseContentTests/StorehouseExpiryTests.swift +++ /dev/null @@ -1,115 +0,0 @@ -// -// StorehouseExpiryTests.swift -// -// Copyright (c) 2020 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -@testable import Cloudinary -import Foundation -import XCTest - -class StorehouseExpiryTests: XCTestCase { - - var sut : StorehouseExpiry! - - override func tearDownWithError() throws { - - sut = nil - - super.tearDown() - } - - // MARK: - init - func test_init_shouldBeInitialized() { - - // Given - sut = .never - - // Then - XCTAssertNotNil(sut, "sut should be initialized") - } - - // MARK: - isExpired - func test_isExpired_never_shouldNotBeExpired() { - - // Given - sut = .never - - // Then - XCTAssertFalse(sut.isExpired, "sut should not be expired") - } - func test_isExpired_secondsFrom1970_shouldNotBeExpired() { - - // Given - sut = .secondsFrom1970(60 * 60 * 24 * 365 * 70) - - // Then - XCTAssertFalse(sut.isExpired, "sut should not be expired") - } - func test_isExpired_date_shouldNotBeExpired() { - - // Given - sut = .date(Date() + 10) - - // Then - XCTAssertFalse(sut.isExpired, "sut should not be expired") - } - func test_isExpired_oldDate_shouldBeExpired() { - - // Given - sut = .date(Date() - 10) - - // Then - XCTAssertTrue(sut.isExpired, "sut should be expired") - } - func test_isExpiredForBase_never_shouldNotBeExpired() { - - // Given - sut = .never - - // Then - XCTAssertFalse(sut.isExpired(for: Date()), "sut should not be expired") - } - func test_isExpiredForBase_secondsFrom1970_shouldNotBeExpired() { - - // Given - sut = .secondsFrom1970(60 * 60 * 24 * 365 * 70) - - // Then - XCTAssertFalse(sut.isExpired(for: Date()), "sut should not be expired") - } - func test_isExpiredForBase_date_shouldNotBeExpired() { - - // Given - sut = .date(Date() + 10) - - // Then - XCTAssertFalse(sut.isExpired(for: Date()), "sut should not be expired") - } - func test_isExpiredForBase_oldDate_shouldBeExpired() { - - // Given - sut = .date(Date() - 10) - - // Then - XCTAssertTrue(sut.isExpired(for: Date()), "sut should be expired") - } -} diff --git a/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/StorehouseContentTests/StorehouseTransformerTests.swift b/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/StorehouseContentTests/StorehouseTransformerTests.swift deleted file mode 100644 index d78ef019..00000000 --- a/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/StorehouseContentTests/StorehouseTransformerTests.swift +++ /dev/null @@ -1,65 +0,0 @@ -// -// StorehouseTransformerTests.swift -// -// Copyright (c) 2020 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -@testable import Cloudinary -import Foundation -import XCTest - -class StorehouseTransformerTests: XCTestCase { - - var sut : StorehouseTransformer! - - override func tearDownWithError() throws { - - sut = nil - super.tearDown() - } - - // MARK: - init - func test_init_default_shouldBeInitialized() { - - // Given - let toData : StorehouseTransformer.StorehouseEncode = { string in - if let data = string.data(using: .utf8) { - return data - } - return Data() - } - let fromData : StorehouseTransformer.StorehouseDecode = { data in - - if let string = String.init(data: data, encoding: .utf8){ - return string - } - return "" - } - - // When - sut = StorehouseTransformer(toData: toData, fromData: fromData) - - // Then - XCTAssertNotNil(sut, "sut should be initialized") - XCTAssertNotNil(sut.toData, "initialized value should be set") - XCTAssertNotNil(sut.fromData, "initialized value should be set") - } -} diff --git a/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/StorehouseHybridTests/StorehouseHybridTests.swift b/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/StorehouseHybridTests/StorehouseHybridTests.swift deleted file mode 100644 index 63a3d97e..00000000 --- a/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/StorehouseHybridTests/StorehouseHybridTests.swift +++ /dev/null @@ -1,121 +0,0 @@ -// -// StorehouseHybridTests.swift -// -// Copyright (c) 2020 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -@testable import Cloudinary -import Foundation -import XCTest - -class StorehouseHybridTests: BaseStorehouseAnyTests> { - - let maximumSizeDisk = 100_000_000 - - override func setUp() { - super.setUp() - - sut = createSut() - } - - func createSut() -> StorehouseHybrid! { - - // create storehouseOnDisk - let nameDisk : String = "nameTest" - let expiryDateDisk : Date = Date() - let expiryDisk : StorehouseExpiry = .date(expiryDateDisk) - let maxSizeDisk : Int = maximumSizeDisk - let protectionTypeDisk: FileProtectionType? = .complete - - let configuration = StorehouseConfigurationDisk(name: nameDisk , expiry: expiryDisk , maxSize: maxSizeDisk, protectionType: protectionTypeDisk) - let transformer = WarehouseTransformerFactory.forCodable(ofType: String.self) - - let storehouseOnDisk: StorehouseOnDisk = try! StorehouseOnDisk(configuration: configuration, transformer: transformer) - - // create storehouseInMemory - let expiryDateMemory : Date = Date() - let expiryMemory : StorehouseExpiry = .date(expiryDateMemory) - let countLimitMemory : UInt = 100_000_000 - let totalCostLimitMemory: UInt = 100_000_000 - let configurationMemory = StorehouseConfigurationInMemory(expiry: expiryMemory, countLimit: countLimitMemory, totalCostLimit: totalCostLimitMemory) - - let storehouseInMemory: StorehouseInMemory = StorehouseInMemory(configuration: configurationMemory) - - // create storehouseHybrid - return StorehouseHybrid(inMemory: storehouseInMemory, onDisk: storehouseOnDisk) - } - - override func tearDownWithError() throws { - try? sut.removeAll() - sut = nil - - super.tearDown() - } - - // MARK: - init - func test_init_shouldBeInitialized() { - - // When - let tempSut = createSut() - - // Then - XCTAssertNotNil(tempSut, "sut should be initialized") - } - - // MARK: - vars - func test_vars_shouldReturnExpectedValues() { - - // Given - let expectedMemoryCapacity = NSNotFound - let expectedDiskCapacity = maximumSizeDisk - let expectedMemoryUsage = NSNotFound - let expectedDiskUsage = 25 - - let objectToSave = "objectToSave" - let savedObjectKey = "key" - - // When - try? sut.setObject(objectToSave, forKey: savedObjectKey) - - // Then - XCTAssertEqual(sut.memoryCapacity, expectedMemoryCapacity, "initialized value should be equal to expected value") - XCTAssertEqual(sut.diskCapacity, expectedDiskCapacity, "initialized value should be equal to expected value") - XCTAssertEqual(sut.currentMemoryUsage, expectedMemoryUsage, "initialized value should be equal to expected value") - XCTAssertEqual(sut.currentDiskUsage, expectedDiskUsage, "initialized value should be equal to expected value") - } - func test_vars_diskUsage_shouldReturnExpectedValue() { - - // Given - let objectToSave1 = "objectToSave1" - let savedObjectKey1 = "key1" - let objectToSave2 = "objectToSave2" - let savedObjectKey2 = "key2" - let expectedDiskUsage = 52 - - // When - try? sut.setObject(objectToSave1, forKey: savedObjectKey1) - try? sut.setObject(objectToSave2, forKey: savedObjectKey2) - let currentDiskUsage = sut.currentDiskUsage - - // Then - XCTAssertEqual(currentDiskUsage, expectedDiskUsage, "entered strings should use expected disk space") - } -} diff --git a/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/WarehouseTests/WarehouseTests.swift b/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/WarehouseTests/WarehouseTests.swift deleted file mode 100644 index 41a9f40a..00000000 --- a/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/WarehouseTests/WarehouseTests.swift +++ /dev/null @@ -1,366 +0,0 @@ -// -// WarehouseTests.swift -// -// Copyright (c) 2020 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -@testable import Cloudinary -import Foundation -import XCTest - -class WarehouseTests: XCTestCase { - - var sut : Warehouse! - let maximumSizeDisk = 100_000_000 - - override func setUp() { - super.setUp() - - sut = createHybridSut() - } - - func createHybridSut() -> Warehouse! { - - // create storehouseOnDisk - let nameDisk : String = "nameTest" - let expiryDateDisk : Date = Date() - let expiryDisk : StorehouseExpiry = .date(expiryDateDisk) - let maxSizeDisk : Int = maximumSizeDisk - let protectionTypeDisk: FileProtectionType? = .complete - - let configuration = StorehouseConfigurationDisk(name: nameDisk , expiry: expiryDisk , maxSize: maxSizeDisk, protectionType: protectionTypeDisk) - let transformer = WarehouseTransformerFactory.forCodable(ofType: String.self) - - let storehouseOnDisk: StorehouseOnDisk = try! StorehouseOnDisk(configuration: configuration, transformer: transformer) - - // create storehouseInMemory - let expiryDateMemory : Date = Date() - let expiryMemory : StorehouseExpiry = .date(expiryDateMemory) - let countLimitMemory : UInt = 100_000_000 - let totalCostLimitMemory: UInt = 100_000_000 - let configurationMemory = StorehouseConfigurationInMemory(expiry: expiryMemory, countLimit: countLimitMemory, totalCostLimit: totalCostLimitMemory) - - let storehouseInMemory: StorehouseInMemory = StorehouseInMemory(configuration: configurationMemory) - - // create storehouseHybrid - let storehouseHybrid = StorehouseHybrid(inMemory: storehouseInMemory, onDisk: storehouseOnDisk) - - return Warehouse(hybrid: storehouseHybrid) - } - func createMemorySut() -> Warehouse! { - - // in memory configuration - let expiryDateMemory : Date = Date() - let expiryMemory : StorehouseExpiry = .date(expiryDateMemory) - let countLimitMemory : UInt = 100_000_000 - let totalCostLimitMemory: UInt = 100_000_000 - - let configurationMemory = StorehouseConfigurationInMemory(expiry: expiryMemory, countLimit: countLimitMemory, totalCostLimit: totalCostLimitMemory) - - // on disk configuration - let nameDisk : String = "nameTest" - let expiryDateDisk : Date = Date() - let expiryDisk : StorehouseExpiry = .date(expiryDateDisk) - let maxSizeDisk : Int = maximumSizeDisk - let protectionTypeDisk: FileProtectionType? = .complete - - let configurationDisk = StorehouseConfigurationDisk(name: nameDisk , expiry: expiryDisk , maxSize: maxSizeDisk, protectionType: protectionTypeDisk) - - let transformer = WarehouseTransformerFactory.forCodable(ofType: String.self) - - return try? Warehouse(memoryConfig: configurationMemory, diskConfig: configurationDisk, transformer: transformer) - } - func createAutopurgeSut() -> Warehouse! { - - // autopurge configuration - let expiryDate : Date = Date() - let expiry : StorehouseExpiry = .date(expiryDate) - let memory : Int = 100_000_000 - let afterPurge : Int = 60_000_000 - - let configurationAutoPurge = StorehouseConfigurationAutoPurging(expiry: expiry, memory: memory, preferredMemoryUsageAfterPurge: afterPurge) - - // on disk configuration - let nameDisk : String = "nameTest" - let expiryDateDisk : Date = Date() - let expiryDisk : StorehouseExpiry = .date(expiryDateDisk) - let maxSizeDisk : Int = maximumSizeDisk - let protectionTypeDisk: FileProtectionType? = .complete - - let configurationDisk = StorehouseConfigurationDisk(name: nameDisk , expiry: expiryDisk , maxSize: maxSizeDisk, protectionType: protectionTypeDisk) - - let transformer = WarehouseTransformerFactory.forCodable(ofType: String.self) - - return try? Warehouse(purgingConfig: configurationAutoPurge, diskConfig: configurationDisk, transformer: transformer) - } - - override func tearDownWithError() throws { - try? sut.removeAll() - sut = nil - - super.tearDown() - } - - // MARK: - init - func test_init_hybrid_shouldBeInitialized() { - - // When - let tempSut = createHybridSut() - - // Then - XCTAssertNotNil(tempSut, "sut should be initialized") - } - func test_init_memory_shouldBeInitialized() { - - // When - let tempSut = createMemorySut() - - // Then - XCTAssertNotNil(tempSut, "sut should be initialized") - } - func test_init_autopurge_shouldBeInitialized() { - - // When - let tempSut = createAutopurgeSut() - - // Then - XCTAssertNotNil(tempSut, "sut should be initialized") - } - - // MARK: - vars - func test_vars_shouldReturnExpectedValue() { - - // Given - let expectedMemoryCapacity = NSNotFound - let expectedDiskCapacity = maximumSizeDisk - let expectedMemoryUsage = NSNotFound - let expectedDiskUsage = 25 - - let objectToSave = "objectToSave" - let savedObjectKey = "key" - - // When - try? sut.setObject(objectToSave, forKey: savedObjectKey) - - // Then - XCTAssertEqual(sut.memoryCapacity, expectedMemoryCapacity, "initialized value should be equal to expected value") - XCTAssertEqual(sut.diskCapacity, expectedDiskCapacity, "initialized value should be equal to expected value") - XCTAssertEqual(sut.currentMemoryUsage, expectedMemoryUsage, "initialized value should be equal to expected value") - XCTAssertEqual(sut.currentDiskUsage, expectedDiskUsage, "initialized value should be equal to expected value") - } - func test_vars_diskCapacity_shouldReturnExpectedValue() { - - // Given - let objectToSave1 = "objectToSave1" - let savedObjectKey1 = "key1" - let objectToSave2 = "objectToSave2" - let savedObjectKey2 = "key2" - let expectedDiskUsage = 52 - - // When - try? sut.setObject(objectToSave1, forKey: savedObjectKey1) - try? sut.setObject(objectToSave2, forKey: savedObjectKey2) - let currentDiskUsage = sut.currentDiskUsage - - // Then - XCTAssertEqual(currentDiskUsage, expectedDiskUsage, "entered strings should use expected disk space") - } - func test_vars_memoryCapacity_shouldReturnExpectedValue() { - - // Given - let objectToSave1 = "objectToSave1" - let savedObjectKey1 = "key1" - let objectToSave2 = "objectToSave2" - let savedObjectKey2 = "key2" - let expectedDiskUsage = 52 - - // When - try? sut.setObject(objectToSave1, forKey: savedObjectKey1) - try? sut.setObject(objectToSave2, forKey: savedObjectKey2) - let currentDiskUsage = sut.currentDiskUsage - - // Then - XCTAssertEqual(currentDiskUsage, expectedDiskUsage, "entered strings should use expected disk space") - } - func test_vars_currentMemoryUsage_shouldReturnExpectedValue() { - - // Given - let objectToSave1 = "objectToSave1" - let savedObjectKey1 = "key1" - let objectToSave2 = "objectToSave2" - let savedObjectKey2 = "key2" - let expectedDiskUsage = 52 - - // When - try? sut.setObject(objectToSave1, forKey: savedObjectKey1) - try? sut.setObject(objectToSave2, forKey: savedObjectKey2) - let currentDiskUsage = sut.currentDiskUsage - - // Then - XCTAssertEqual(currentDiskUsage, expectedDiskUsage, "entered strings should use expected disk space") - } - - // MARK: - funcs - func test_funcs_emptyEntry_shouldReturnNil() { - - let entry = try? sut.entry(forKey: "key") - - // Then - XCTAssertNil(entry, "uninserted value should be nil") - } - func test_funcs_setObjectAndEntry_objectShouldBeSet() { - - // Given - let objectToSave = "objectToSave" - let savedObjectKey = "key" - - // When - try? sut.setObject(objectToSave, forKey: savedObjectKey) - let entry = try? sut.entry(forKey: savedObjectKey).object - - // Then - XCTAssertEqual(entry, objectToSave, "object should be set") - } - func test_funcs_removeAll_shouldReturnNil() { - - // Given - let objectToSave = "objectToSave" - let savedObjectKey = "key" - - // When - try? sut.setObject(objectToSave, forKey: savedObjectKey) - try? sut.removeAll() - - let entry = try? sut.entry(forKey: savedObjectKey).object - - // Then - XCTAssertNil(entry, "removed value should be nil") - } - func test_funcs_removeByKey_shouldReturnNil() { - - // Given - let objectToSave = "objectToSave" - let savedObjectKey = "key" - - // When - try? sut.setObject(objectToSave, forKey: savedObjectKey) - try? sut.removeObject(forKey: savedObjectKey) - - let entry = try? sut.entry(forKey: savedObjectKey).object - - // Then - XCTAssertNil(entry, "removed value should be nil") - } - func test_funcs_removeObjectIfExpired_shouldReturnNil() { - - // Given - let objectToSave = "objectToSave" - let savedObjectKey = "key" - - // When - try? sut.setObject(objectToSave, forKey: savedObjectKey) - try? sut.removeObjectIfExpired(forKey: savedObjectKey) - - let entry = try? sut.entry(forKey: savedObjectKey).object - - // Then - XCTAssertNil(entry, "removed value should be nil") - } - func test_funcs_removeExpiredObjects_shouldReturnNil() { - - // Given - let objectToSave1 = "objectToSave1" - let savedObjectKey1 = "key1" - let objectToSave2 = "objectToSave2" - let savedObjectKey2 = "key2" - - // When - try? sut.setObject(objectToSave1, forKey: savedObjectKey1) - try? sut.setObject(objectToSave2, forKey: savedObjectKey2) - try? sut.removeExpiredObjects() - - let entry1 = try? sut.entry(forKey: savedObjectKey1).object - let entry2 = try? sut.entry(forKey: savedObjectKey2).object - - // Then - XCTAssertNil(entry1, "removed value should be nil") - XCTAssertNil(entry2, "removed value should be nil") - } - func test_funcs_removeStoredObjects_shouldReturnNil() { - - // Given - let objectToSave1 = "objectToSave1" - let savedObjectKey1 = "key1" - let objectToSave2 = "objectToSave2" - let savedObjectKey2 = "key2" - - // When - try? sut.setObject(objectToSave1, forKey: savedObjectKey1) - try? sut.setObject(objectToSave2, forKey: savedObjectKey2) - try? sut.removeStoredObjects(since: Date()) - - let entry1 = try? sut.entry(forKey: savedObjectKey1).object - let entry2 = try? sut.entry(forKey: savedObjectKey2).object - - // Then - XCTAssertNil(entry1, "removed value should be nil") - XCTAssertNil(entry2, "removed value should be nil") - } - func test_funcs_Object_objectShouldBeSet() { - - // Given - let objectToSave = "objectToSave" - let savedObjectKey = "key" - - // When - try? sut.setObject(objectToSave, forKey: savedObjectKey) - let entry = try? sut.object(forKey: savedObjectKey) - - // Then - XCTAssertEqual(entry, objectToSave, "object should be set") - } - func test_funcs_exists_objectShouldBeExists() { - - // Given - let objectToSave = "objectToSave" - let savedObjectKey = "key" - - // When - try? sut.setObject(objectToSave, forKey: savedObjectKey) - let objectExists = try? sut.existsObject(forKey: savedObjectKey) - - // Then - XCTAssert(objectExists == true, "object should be set") - } - func test_funcs_expired_objectShouldBeExpired() { - - // Given - let objectToSave = "objectToSave" - let savedObjectKey = "key" - - // When - try? sut.setObject(objectToSave, forKey: savedObjectKey) - let objectExpired = try? sut.isExpiredObject(forKey: savedObjectKey) - - // Then - XCTAssertTrue(objectExpired == true, "object should be expired") - } -} diff --git a/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/WarehouseTests/WarehouseTransformerFactoryTests.swift b/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/WarehouseTests/WarehouseTransformerFactoryTests.swift deleted file mode 100644 index f22b00ea..00000000 --- a/Example/Tests/BaseNetwork/Features/CLDURLCacheTests/StorehouseLibraryTests/WarehouseTests/WarehouseTransformerFactoryTests.swift +++ /dev/null @@ -1,67 +0,0 @@ -// -// WarehouseTransformerFactoryTests.swift -// -// Copyright (c) 2020 Cloudinary (http://cloudinary.com) -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// - -@testable import Cloudinary -import Foundation -import XCTest - -class WarehouseTransformerFactoryTests: XCTestCase { - - @objc(codingClass) - class codingClass: NSObject, NSCoding, Codable { - func encode(with coder: NSCoder) {} - required init?(coder: NSCoder) {} - } - - // MARK: - create trasformer - func test_createTrasformer_codeable_shouldBeCreated() { - - // When - let transformer = WarehouseTransformerFactory.forCodable(ofType: codingClass.self) - - // Then - XCTAssertNotNil(transformer.toData, "sut should be initialized") - XCTAssertNotNil(transformer.fromData, "sut should be initialized") - } - - func test_createTrasformer_coding_shouldBeCreated() { - - // When - let transformer = WarehouseTransformerFactory.forCoding(ofType: codingClass.self) - - // Then - XCTAssertNotNil(transformer.toData, "sut should be initialized") - XCTAssertNotNil(transformer.fromData, "sut should be initialized") - } - - func test_createTrasformer_securedCoding_shouldBeCreated() { - - // When - let transformer = WarehouseTransformerFactory.forSecuredCoding(ofType: codingClass.self) - - // Then - XCTAssertNotNil(transformer.toData, "sut should be initialized") - XCTAssertNotNil(transformer.fromData, "sut should be initialized") - } -} diff --git a/Example/Tests/NetworkTests/DownloaderAssetTests.swift b/Example/Tests/NetworkTests/DownloaderAssetTests.swift index d3c5e702..59b6861f 100644 --- a/Example/Tests/NetworkTests/DownloaderAssetTests.swift +++ b/Example/Tests/NetworkTests/DownloaderAssetTests.swift @@ -39,7 +39,7 @@ class DownloaderAssetTests: NetworkBaseTest { override func tearDown() { - sut.downloadCoordinator.urlCache.removeAllCachedResponses() + CLDDownloadCoordinator.urlCache.removeAllCachedResponses() sut = nil super.tearDown() } @@ -96,11 +96,6 @@ extension DownloaderAssetTests { XCTAssertNotNil(cloudinary!.config.apiSecret, "Must set api secret for this test") - if !shouldCache { - cloudinary!.cacheAssetMaxMemoryTotalCost = 20 - cloudinary!.cacheAssetMaxDiskCapacity = 20 - } - // Given let resource: TestResourceType = testResource var publicId: String? @@ -128,7 +123,7 @@ extension DownloaderAssetTests { /// download asset by publicId let url = cloudinary!.createUrl().setResourceType(resourceType).generate(pubId) - sut.fetchAsset(url!).responseAsset { (responseData, err) in + let request = sut.fetchAsset(url!).responseAsset { (responseData, err) in response = responseData expectation.fulfill() } @@ -137,13 +132,6 @@ extension DownloaderAssetTests { // Then XCTAssertEqual(response, resource.data, "uploaded data should be equal to downloaded data") - - if shouldCache { - XCTAssertNotNil(try sut.downloadCoordinator.urlCache.warehouse.entry(forKey: url!), "response should be cached") - } - else { - XCTAssertThrowsError(try sut.downloadCoordinator.urlCache.warehouse.entry(forKey: url!), "response should not be cached") - } } } diff --git a/Example/Tests/NetworkTests/DownloaderTests.swift b/Example/Tests/NetworkTests/DownloaderTests.swift index a9335deb..a65fac74 100644 --- a/Example/Tests/NetworkTests/DownloaderTests.swift +++ b/Example/Tests/NetworkTests/DownloaderTests.swift @@ -102,8 +102,7 @@ class DownloaderTests: NetworkBaseTest { XCTAssertNil(error, "error should be nil") } func test_downloadImageWithCache_shouldCacheAndRemoveImage() { - cloudinarySecured.enableUrlCache = false - cloudinarySecured.cachePolicy = .disk + cloudinarySecured.enableUrlCache = true downloadImageWithCache_shouldCacheImage(cloudinaryObject: cloudinarySecured) } func test_downloadImageWithoutCache_shouldCacheImage() { @@ -122,8 +121,7 @@ class DownloaderTests: NetworkBaseTest { // When let tempSut = CLDCloudinary(configuration: config, networkAdapter: nil, downloadAdapter: nil, sessionConfiguration: nil, downloadSessionConfiguration: nil) - tempSut.enableUrlCache = false - tempSut.cachePolicy = .disk + tempSut.enableUrlCache = true downloadImageWithCache_shouldCacheImage(cloudinaryObject: tempSut) } @@ -194,12 +192,12 @@ extension DownloaderTests { waitForExpectations(timeout: timeout, handler: nil) // Then - XCTAssertEqual(response, responseCached, "Images should be equal because it is the image we cached") + XCTAssertEqual(response?.pngData()?.count, responseCached?.pngData()?.count, "Images should be equal because it is the image we cached") expectation = self.expectation(description: "Download 3 should succeed") /// remove from cache and re-download - image should be different - cloudinaryObject.removeFromCache(key: url!) +// cloudinaryObject.removeFromCache(key: url!) cloudinaryObject.createDownloader().fetchImage(url!).responseImage({ (responseImage, errorRes) in responseCached = responseImage diff --git a/Example/Tests/UIExtensions/UIBaseTest.swift b/Example/Tests/UIExtensions/UIBaseTest.swift index a26c1f86..1bafc70a 100644 --- a/Example/Tests/UIExtensions/UIBaseTest.swift +++ b/Example/Tests/UIExtensions/UIBaseTest.swift @@ -35,7 +35,7 @@ class UIBaseTest: NetworkBaseTest { override func setUp() { super.setUp() - cloudinary!.cachePolicy = .none + cloudinary!.enableUrlCache = false continueAfterFailure = false }