From 430b24a8bd98defd4174f9e24d53cbe0b285c936 Mon Sep 17 00:00:00 2001 From: Ramon Gilabert Date: Mon, 19 Sep 2016 15:28:54 +0200 Subject: [PATCH 1/7] First migration to Swift 3 --- .travis.yml | 4 +- Cache.xcodeproj/project.pbxproj | 17 +- .../xcshareddata/xcschemes/Cache-Mac.xcscheme | 2 +- .../xcshareddata/xcschemes/Cache-iOS.xcscheme | 2 +- Cartfile | 2 +- Cartfile.private | 4 +- Cartfile.resolved | 6 +- Source/Shared/BasicHybridCache.swift | 20 +-- Source/Shared/Cache.swift | 6 +- Source/Shared/Config.swift | 6 +- Source/Shared/DataStructures/Cachable.swift | 4 +- Source/Shared/DataStructures/Capsule.swift | 4 +- Source/Shared/DataStructures/Expiry.swift | 18 +- Source/Shared/DataStructures/JSON.swift | 12 +- .../Shared/DataStructures/StorageKind.swift | 12 +- Source/Shared/Extensions/JSON+Cache.swift | 16 +- Source/Shared/Extensions/NSData+Cache.swift | 8 +- Source/Shared/Extensions/NSDate+Cache.swift | 14 +- Source/Shared/Extensions/String+Cache.swift | 12 +- .../Library/DefaultCacheConverter.swift | 20 +-- Source/Shared/Library/SyncCache.swift | 18 +- Source/Shared/Library/SyncHybridCache.swift | 30 ++-- Source/Shared/Storage/DiskStorage.swift | 154 ++++++++++-------- Source/Shared/Storage/MemoryStorage.swift | 56 +++---- Source/Shared/Storage/StorageAware.swift | 16 +- Source/Shared/Storage/StorageFactory.swift | 16 +- Source/iOS/Extensions/UIImage+Cache.swift | 9 +- Source/iOS/HybridCache.swift | 28 ++-- Tests/iOS/Helpers/SpecHelper.swift | 14 +- Tests/iOS/Helpers/UIImage+CacheTests.swift | 10 +- Tests/iOS/Helpers/User.swift | 6 +- Tests/iOS/Specs/CacheSpec.swift | 28 ++-- .../Specs/DataStructures/CapsuleSpec.swift | 4 +- .../iOS/Specs/DataStructures/ExpirySpec.swift | 6 +- .../iOS/Specs/Extensions/JSON+CacheSpec.swift | 16 +- .../Specs/Extensions/NSData+CacheSpec.swift | 2 +- .../Specs/Extensions/NSDate+CacheSpec.swift | 14 +- .../Specs/Extensions/String+CacheSpec.swift | 4 +- .../Library/DefaultCacheConverterSpec.swift | 8 +- Tests/iOS/Specs/Storage/DiskStorageSpec.swift | 52 +++--- .../iOS/Specs/Storage/MemoryStorageSpec.swift | 46 +++--- 41 files changed, 381 insertions(+), 345 deletions(-) diff --git a/.travis.yml b/.travis.yml index a80059a4..41758e6c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,4 @@ -osx_image: xcode7.3 +osx_image: xcode8 language: objective-c before_install: @@ -10,4 +10,4 @@ script: - xcodebuild clean build -project Cache.xcodeproj -scheme "Cache-Mac" -sdk macosx - xcodebuild test -project Cache.xcodeproj -scheme "Cache-Mac" -sdk macosx - xcodebuild clean build -project Cache.xcodeproj -scheme "Cache-iOS" -sdk iphonesimulator -- xcodebuild test -project Cache.xcodeproj -scheme "Cache-iOS" -sdk iphonesimulator +- xcodebuild test -project Cache.xcodeproj -scheme "Cache-iOS" -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 6,OS=10.0' diff --git a/Cache.xcodeproj/project.pbxproj b/Cache.xcodeproj/project.pbxproj index 0e7831d5..edea8274 100644 --- a/Cache.xcodeproj/project.pbxproj +++ b/Cache.xcodeproj/project.pbxproj @@ -602,11 +602,12 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0720; - LastUpgradeCheck = 0720; + LastUpgradeCheck = 0800; ORGANIZATIONNAME = "Hyper Interaktiv AS"; TargetAttributes = { D5291D171C2837DB00B702C9 = { CreatedOnToolsVersion = 7.2; + LastSwiftMigration = 0800; }; D5291D5F1C283B5300B702C9 = { CreatedOnToolsVersion = 7.2; @@ -616,6 +617,7 @@ }; D5DC59DF1C20593E003BD79B = { CreatedOnToolsVersion = 7.2; + LastSwiftMigration = 0800; }; }; }; @@ -866,6 +868,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "no.hyper.Cache-iOS-Tests"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; }; name = Debug; }; @@ -880,6 +883,7 @@ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_BUNDLE_IDENTIFIER = "no.hyper.Cache-iOS-Tests"; PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 3.0; }; name = Release; }; @@ -982,8 +986,10 @@ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -1011,6 +1017,7 @@ ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; @@ -1030,8 +1037,10 @@ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -1051,6 +1060,8 @@ IPHONEOS_DEPLOYMENT_TARGET = 9.2; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; VERSIONING_SYSTEM = "apple-generic"; @@ -1061,6 +1072,7 @@ D5DC59F51C20593E003BD79B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -1077,12 +1089,14 @@ PRODUCT_BUNDLE_IDENTIFIER = no.hyper.Cache; PRODUCT_NAME = Cache; SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; }; name = Debug; }; D5DC59F61C20593E003BD79B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; DEFINES_MODULE = YES; DYLIB_COMPATIBILITY_VERSION = 1; DYLIB_CURRENT_VERSION = 1; @@ -1099,6 +1113,7 @@ PRODUCT_BUNDLE_IDENTIFIER = no.hyper.Cache; PRODUCT_NAME = Cache; SKIP_INSTALL = YES; + SWIFT_VERSION = 3.0; }; name = Release; }; diff --git a/Cache.xcodeproj/xcshareddata/xcschemes/Cache-Mac.xcscheme b/Cache.xcodeproj/xcshareddata/xcschemes/Cache-Mac.xcscheme index b5159da0..646b3aa2 100644 --- a/Cache.xcodeproj/xcshareddata/xcschemes/Cache-Mac.xcscheme +++ b/Cache.xcodeproj/xcshareddata/xcschemes/Cache-Mac.xcscheme @@ -1,6 +1,6 @@ (key: String, object: T, expiry: Expiry? = nil, completion: (() -> Void)? = nil) { + open func add(_ key: String, object: T, expiry: Expiry? = nil, completion: (() -> Void)? = nil) { let expiry = expiry ?? config.expiry frontStorage.add(key, object: object, expiry: expiry) { [weak self] in @@ -69,20 +69,20 @@ public class BasicHybridCache: NSObject { - Parameter key: Unique key to identify the object in the cache - Parameter completion: Completion closure returns object or nil */ - public func object(key: String, completion: (object: T?) -> Void) { + open func object(_ key: String, completion: @escaping (_ object: T?) -> Void) { frontStorage.object(key) { [weak self] (object: T?) in if let object = object { - completion(object: object) + completion(object) return } guard let weakSelf = self else { - completion(object: object) + completion(object) return } weakSelf.backStorage.object(key) { (object: T?) in - completion(object: object) + completion(object) } } } @@ -93,7 +93,7 @@ public class BasicHybridCache: NSObject { - Parameter key: Unique key to identify the object in the cache - Parameter completion: Completion closure to be called when the task is done */ - public func remove(key: String, completion: (() -> Void)? = nil) { + open func remove(_ key: String, completion: (() -> Void)? = nil) { frontStorage.remove(key) { [weak self] in guard let weakSelf = self else { completion?() @@ -111,7 +111,7 @@ public class BasicHybridCache: NSObject { - Parameter completion: Completion closure to be called when the task is done */ - public func clear(completion: (() -> Void)? = nil) { + open func clear(_ completion: (() -> Void)? = nil) { frontStorage.clear() { [weak self] in guard let weakSelf = self else { completion?() diff --git a/Source/Shared/Cache.swift b/Source/Shared/Cache.swift index 48122159..cc5b007c 100644 --- a/Source/Shared/Cache.swift +++ b/Source/Shared/Cache.swift @@ -5,7 +5,7 @@ import Foundation Cachable protocol. It's two layered cache (with front and back storages). Subscribes to system notifications to clear expired cached objects. */ -public class Cache: HybridCache { +open class Cache: HybridCache { // MARK: - Initialization @@ -29,7 +29,7 @@ public class Cache: HybridCache { - Parameter expiry: Expiration date for the cached object - Parameter completion: Completion closure to be called when the task is done */ - public override func add(key: String, object: T, expiry: Expiry? = nil, completion: (() -> Void)? = nil) { + open override func add(_ key: String, object: T, expiry: Expiry? = nil, completion: (() -> Void)? = nil) { super.add(key, object: object, expiry: expiry, completion: completion) } @@ -39,7 +39,7 @@ public class Cache: HybridCache { - Parameter key: Unique key to identify the object in the cache - Parameter completion: Completion closure returns object or nil */ - public override func object(key: String, completion: (object: T?) -> Void) { + open override func object(_ key: String, completion: @escaping (_ object: T?) -> Void) { super.object(key, completion: completion) } } diff --git a/Source/Shared/Config.swift b/Source/Shared/Config.swift index 03fb6eea..f20aab43 100644 --- a/Source/Shared/Config.swift +++ b/Source/Shared/Config.swift @@ -26,7 +26,7 @@ public struct Config { - Parameter maxSize: Maximum size of the cache storage - Parameter maxObjects: Maximum amount of objects to be stored in memory */ - public init(frontKind: StorageKind, backKind: StorageKind, expiry: Expiry = .Never, maxSize: UInt = 0, maxObjects: Int = 0) { + public init(frontKind: StorageKind, backKind: StorageKind, expiry: Expiry = .never, maxSize: UInt = 0, maxObjects: Int = 0) { self.frontKind = frontKind self.backKind = backKind self.expiry = expiry @@ -44,7 +44,7 @@ extension Config { */ public static var defaultConfig: Config { return Config( - frontKind: .Memory, - backKind: .Disk) + frontKind: .memory, + backKind: .disk) } } diff --git a/Source/Shared/DataStructures/Cachable.swift b/Source/Shared/DataStructures/Cachable.swift index 7d2d2838..5e936aae 100644 --- a/Source/Shared/DataStructures/Cachable.swift +++ b/Source/Shared/DataStructures/Cachable.swift @@ -12,10 +12,10 @@ public protocol Cachable { - Parameter data: Data to decode from */ - static func decode(data: NSData) -> CacheType? + static func decode(_ data: Data) -> CacheType? /** Encodes an instance to NSData */ - func encode() -> NSData? + func encode() -> Data? } diff --git a/Source/Shared/DataStructures/Capsule.swift b/Source/Shared/DataStructures/Capsule.swift index f003178f..5813658d 100644 --- a/Source/Shared/DataStructures/Capsule.swift +++ b/Source/Shared/DataStructures/Capsule.swift @@ -9,7 +9,7 @@ class Capsule: NSObject { /// Object to be cached let value: Any /// Expiration date - let expiryDate: NSDate + let expiryDate: Date /// Checks if cached object is expired according to expiration date var expired: Bool { @@ -26,6 +26,6 @@ class Capsule: NSObject { */ init(value: Any, expiry: Expiry) { self.value = value - self.expiryDate = expiry.date + self.expiryDate = expiry.date as Date } } diff --git a/Source/Shared/DataStructures/Expiry.swift b/Source/Shared/DataStructures/Expiry.swift index dae90710..a03e92a7 100644 --- a/Source/Shared/DataStructures/Expiry.swift +++ b/Source/Shared/DataStructures/Expiry.swift @@ -5,22 +5,22 @@ import Foundation */ public enum Expiry { /// Object will be expired in the nearest future - case Never + case never /// Object will be expired in the specified amount of seconds - case Seconds(NSTimeInterval) + case seconds(TimeInterval) /// Object will be expired on the specified date - case Date(NSDate) + case Date(Foundation.Date) /// Returns the appropriate date object - public var date: NSDate { - let result: NSDate + public var date: Foundation.Date { + let result: Foundation.Date switch self { - case .Never: + case .never: // Ref: http://lists.apple.com/archives/cocoa-dev/2005/Apr/msg01833.html - result = NSDate(timeIntervalSince1970: 60 * 60 * 24 * 365 * 68) - case .Seconds(let seconds): - result = NSDate().dateByAddingTimeInterval(seconds) + result = Foundation.Date(timeIntervalSince1970: 60 * 60 * 24 * 365 * 68) + case .seconds(let seconds): + result = Foundation.Date().addingTimeInterval(seconds) case .Date(let date): result = date } diff --git a/Source/Shared/DataStructures/JSON.swift b/Source/Shared/DataStructures/JSON.swift index 8eb5425f..7bb081fa 100644 --- a/Source/Shared/DataStructures/JSON.swift +++ b/Source/Shared/DataStructures/JSON.swift @@ -5,19 +5,19 @@ import Foundation */ public enum JSON { /// JSON array - case Array([AnyObject]) + case array([AnyObject]) /// JSON dictionary - case Dictionary([String : AnyObject]) + case dictionary([String : AnyObject]) /// Converts value to AnyObject public var object: AnyObject { var result: AnyObject switch self { - case .Array(let object): - result = object - case .Dictionary(let object): - result = object + case .array(let object): + result = object as AnyObject + case .dictionary(let object): + result = object as AnyObject } return result diff --git a/Source/Shared/DataStructures/StorageKind.swift b/Source/Shared/DataStructures/StorageKind.swift index 1ca720f0..976c7ab6 100644 --- a/Source/Shared/DataStructures/StorageKind.swift +++ b/Source/Shared/DataStructures/StorageKind.swift @@ -3,22 +3,22 @@ */ public enum StorageKind { /// Memory storage - case Memory + case memory /// Disk storage - case Disk + case disk /// Custom kind of storage by the given name - case Custom(String) + case custom(String) /// Converts value to appropriate string public var name: String { let result: String switch self { - case .Memory: + case .memory: result = "Memory" - case .Disk: + case .disk: result = "Disk" - case .Custom(let name): + case .custom(let name): result = name } diff --git a/Source/Shared/Extensions/JSON+Cache.swift b/Source/Shared/Extensions/JSON+Cache.swift index 9984bc23..6d3ecf21 100644 --- a/Source/Shared/Extensions/JSON+Cache.swift +++ b/Source/Shared/Extensions/JSON+Cache.swift @@ -3,9 +3,9 @@ import Foundation /// A configuration struct public struct CacheJSONOptions { /// Options used when creating Foundation objects from JSON data - public static var readingOptions: NSJSONReadingOptions = NSJSONReadingOptions() + public static var readingOptions: JSONSerialization.ReadingOptions = JSONSerialization.ReadingOptions() /// Options for writing JSON data. - public static var writeOptions: NSJSONWritingOptions = NSJSONWritingOptions() + public static var writeOptions: JSONSerialization.WritingOptions = JSONSerialization.WritingOptions() } // MARK: - Cachable @@ -24,18 +24,18 @@ extension JSON: Cachable { - Parameter data: Data to decode from - Returns: An optional CacheType */ - public static func decode(data: NSData) -> CacheType? { + public static func decode(_ data: Data) -> CacheType? { var result: CacheType? do { - let object = try NSJSONSerialization.JSONObjectWithData(data, + let object = try JSONSerialization.jsonObject(with: data, options: CacheJSONOptions.readingOptions) switch object { case let dictionary as [String : AnyObject]: - result = JSON.Dictionary(dictionary) + result = JSON.dictionary(dictionary) case let array as [AnyObject]: - result = JSON.Array(array) + result = JSON.array(array) default: result = nil } @@ -49,8 +49,8 @@ extension JSON: Cachable { - Returns: Optional NSData */ - public func encode() -> NSData? { - return try? NSJSONSerialization.dataWithJSONObject(object, + public func encode() -> Data? { + return try? JSONSerialization.data(withJSONObject: object, options: CacheJSONOptions.writeOptions) } } diff --git a/Source/Shared/Extensions/NSData+Cache.swift b/Source/Shared/Extensions/NSData+Cache.swift index 26bee157..63f5ed78 100644 --- a/Source/Shared/Extensions/NSData+Cache.swift +++ b/Source/Shared/Extensions/NSData+Cache.swift @@ -5,9 +5,9 @@ import Foundation /** Implementation of Cachable protocol. */ -extension NSData: Cachable { +extension Data: Cachable { - public typealias CacheType = NSData + public typealias CacheType = Data /** Creates an instance from NSData @@ -15,7 +15,7 @@ extension NSData: Cachable { - Parameter data: Data to decode from - Returns: An optional CacheType */ - public static func decode(data: NSData) -> CacheType? { + public static func decode(_ data: Data) -> CacheType? { return data } @@ -23,7 +23,7 @@ extension NSData: Cachable { Encodes an instance to NSData - Returns: Optional NSData */ - public func encode() -> NSData? { + public func encode() -> Data? { return self } } diff --git a/Source/Shared/Extensions/NSDate+Cache.swift b/Source/Shared/Extensions/NSDate+Cache.swift index 16f0b940..4b5276af 100644 --- a/Source/Shared/Extensions/NSDate+Cache.swift +++ b/Source/Shared/Extensions/NSDate+Cache.swift @@ -5,9 +5,9 @@ import Foundation /** Implementation of Cachable protocol. */ -extension NSDate: Cachable { +extension Date: Cachable { - public typealias CacheType = NSDate + public typealias CacheType = Date /** Creates an instance from NSData @@ -15,16 +15,16 @@ extension NSDate: Cachable { - Parameter data: Data to decode from - Returns: An optional CacheType */ - public static func decode(data: NSData) -> CacheType? { - return NSKeyedUnarchiver.unarchiveObjectWithData(data) as? NSDate + public static func decode(_ data: Data) -> CacheType? { + return NSKeyedUnarchiver.unarchiveObject(with: data) as? Date } /** Encodes an instance to NSData - Returns: Optional NSData */ - public func encode() -> NSData? { - return NSKeyedArchiver.archivedDataWithRootObject(self) + public func encode() -> Data? { + return NSKeyedArchiver.archivedData(withRootObject: self) } } @@ -33,7 +33,7 @@ extension NSDate: Cachable { /** Helper NSDate extension. */ -extension NSDate { +extension Date { /// Checks if the date is in the past var inThePast: Bool { diff --git a/Source/Shared/Extensions/String+Cache.swift b/Source/Shared/Extensions/String+Cache.swift index 6be75493..dd6880c4 100644 --- a/Source/Shared/Extensions/String+Cache.swift +++ b/Source/Shared/Extensions/String+Cache.swift @@ -15,8 +15,8 @@ extension String: Cachable { - Parameter data: Data to decode from - Returns: An optional CacheType */ - public static func decode(data: NSData) -> CacheType? { - guard let string = String(data: data, encoding: NSUTF8StringEncoding) else { + public static func decode(_ data: Data) -> CacheType? { + guard let string = String(data: data, encoding: String.Encoding.utf8) else { return nil } @@ -27,8 +27,8 @@ extension String: Cachable { Encodes a string to NSData - Returns: Optional NSData */ - public func encode() -> NSData? { - return dataUsingEncoding(NSUTF8StringEncoding) + public func encode() -> Data? { + return data(using: String.Encoding.utf8) } } @@ -45,7 +45,7 @@ extension String { - Returns: A base64 encoded string */ func base64() -> String { - guard let data = self.dataUsingEncoding(NSUTF8StringEncoding) else { return self } - return data.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0)) + guard let data = self.data(using: String.Encoding.utf8) else { return self } + return data.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 0)) } } diff --git a/Source/Shared/Library/DefaultCacheConverter.swift b/Source/Shared/Library/DefaultCacheConverter.swift index c6c8161d..b78bda02 100644 --- a/Source/Shared/Library/DefaultCacheConverter.swift +++ b/Source/Shared/Library/DefaultCacheConverter.swift @@ -3,8 +3,8 @@ import Foundation /** Encoding error type */ -public enum EncodingError: ErrorType { - case InvalidSize +public enum EncodingError: Error { + case invalidSize } /** @@ -25,13 +25,13 @@ public struct DefaultCacheConverter { - Parameter data: Data to decode from - Returns: A generic type or throws */ - public func decode(data: NSData) throws -> T { - guard data.length == sizeof(T) else { - throw EncodingError.InvalidSize + public func decode(_ data: Data) throws -> T { + guard data.count == MemoryLayout.size else { + throw EncodingError.invalidSize } - let pointer = UnsafeMutablePointer.alloc(1) - data.getBytes(pointer, length: data.length) + let pointer = UnsafeMutablePointer.allocate(capacity: 1) + (data as NSData).getBytes(pointer, length: data.count) return pointer.move() } @@ -42,10 +42,10 @@ public struct DefaultCacheConverter { - Parameter value: A generic value - Returns: A NSData or throws */ - public func encode(value: T) throws -> NSData { + public func encode(_ value: T) throws -> Data { var value = value - return withUnsafePointer(&value) { p in - NSData(bytes: p, length: sizeofValue(value)) + return withUnsafePointer(to: &value) { p in + Data(bytes: UnsafePointer(p), count: MemoryLayout.size(ofValue: value)) } } } diff --git a/Source/Shared/Library/SyncCache.swift b/Source/Shared/Library/SyncCache.swift index 971cbd9c..f88cd3fa 100644 --- a/Source/Shared/Library/SyncCache.swift +++ b/Source/Shared/Library/SyncCache.swift @@ -28,14 +28,14 @@ public struct SyncCache { - Parameter object: Object that needs to be cached - Parameter expiry: Expiration date for the cached object */ - public func add(key: String, object: T, expiry: Expiry? = nil) { - let semaphore = dispatch_semaphore_create(0) + public func add(_ key: String, object: T, expiry: Expiry? = nil) { + let semaphore = DispatchSemaphore(value: 0) cache.add(key, object: object, expiry: expiry) { - dispatch_semaphore_signal(semaphore) + semaphore.signal() } - dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER) + _ = semaphore.wait(timeout: DispatchTime.distantFuture) } /** @@ -44,17 +44,17 @@ public struct SyncCache { - Parameter key: Unique key to identify the object in the cache - Returns: Found object or nil */ - public func object(key: String) -> T? { + public func object(_ key: String) -> T? { var result: T? - let semaphore = dispatch_semaphore_create(0) + let semaphore = DispatchSemaphore(value: 0) cache.object(key) { (object: T?) in result = object - dispatch_semaphore_signal(semaphore) + semaphore.signal() } - dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER) + _ = semaphore.wait(timeout: DispatchTime.distantFuture) return result } @@ -64,7 +64,7 @@ public struct SyncCache { - Parameter key: Unique key to identify the object in the cache */ - public func remove(key: String) { + public func remove(_ key: String) { SyncHybridCache(cache).remove(key) } diff --git a/Source/Shared/Library/SyncHybridCache.swift b/Source/Shared/Library/SyncHybridCache.swift index a3e5dc1c..26a03b3c 100644 --- a/Source/Shared/Library/SyncHybridCache.swift +++ b/Source/Shared/Library/SyncHybridCache.swift @@ -28,14 +28,14 @@ public struct SyncHybridCache { - Parameter object: Object that needs to be cached - Parameter expiry: Expiration date for the cached object */ - public func add(key: String, object: T, expiry: Expiry? = nil) { - let semaphore = dispatch_semaphore_create(0) + public func add(_ key: String, object: T, expiry: Expiry? = nil) { + let semaphore = DispatchSemaphore(value: 0) cache.add(key, object: object, expiry: expiry) { - dispatch_semaphore_signal(semaphore) + semaphore.signal() } - dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER) + semaphore.wait(timeout: DispatchTime.distantFuture) } /** @@ -44,17 +44,17 @@ public struct SyncHybridCache { - Parameter key: Unique key to identify the object in the cache - Returns: Found object or nil */ - public func object(key: String) -> T? { + public func object(_ key: String) -> T? { var result: T? - let semaphore = dispatch_semaphore_create(0) + let semaphore = DispatchSemaphore(value: 0) cache.object(key) { (object: T?) in result = object - dispatch_semaphore_signal(semaphore) + semaphore.signal() } - dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER) + semaphore.wait(timeout: DispatchTime.distantFuture) return result } @@ -64,26 +64,26 @@ public struct SyncHybridCache { - Parameter key: Unique key to identify the object in the cache */ - public func remove(key: String) { - let semaphore = dispatch_semaphore_create(0) + public func remove(_ key: String) { + let semaphore = DispatchSemaphore(value: 0) cache.remove(key) { - dispatch_semaphore_signal(semaphore) + semaphore.signal() } - dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER) + semaphore.wait(timeout: DispatchTime.distantFuture) } /** Clears the front and back cache storages. */ public func clear() { - let semaphore = dispatch_semaphore_create(0) + let semaphore = DispatchSemaphore(value: 0) cache.clear() { - dispatch_semaphore_signal(semaphore) + semaphore.signal() } - dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER) + semaphore.wait(timeout: DispatchTime.distantFuture) } } diff --git a/Source/Shared/Storage/DiskStorage.swift b/Source/Shared/Storage/DiskStorage.swift index c616b520..4533dbee 100644 --- a/Source/Shared/Storage/DiskStorage.swift +++ b/Source/Shared/Storage/DiskStorage.swift @@ -1,28 +1,48 @@ import Foundation import CryptoSwift +fileprivate func < (lhs: T?, rhs: T?) -> Bool { + switch (lhs, rhs) { + case let (l?, r?): + return l < r + case (nil, _?): + return true + default: + return false + } +} + +fileprivate func > (lhs: T?, rhs: T?) -> Bool { + switch (lhs, rhs) { + case let (l?, r?): + return l > r + default: + return rhs < lhs + } +} + /** File-based cache storage */ -public class DiskStorage: StorageAware { +open class DiskStorage: StorageAware { /// Domain prefix - public static let prefix = "no.hyper.Cache.Disk" + open static let prefix = "no.hyper.Cache.Disk" /// Storage root path - public let path: String + open let path: String /// Maximum size of the cache storage - public var maxSize: UInt + open var maxSize: UInt /// Queue for write operations - public private(set) var writeQueue: dispatch_queue_t + open fileprivate(set) var writeQueue: DispatchQueue /// Queue for read operations - public private(set) var readQueue: dispatch_queue_t + open fileprivate(set) var readQueue: DispatchQueue /// File manager to read/write to the disk - private lazy var fileManager: NSFileManager = { - let fileManager = NSFileManager() + fileprivate lazy var fileManager: FileManager = { + let fileManager = FileManager() return fileManager - }() + }() // MARK: - Initialization @@ -34,15 +54,15 @@ public class DiskStorage: StorageAware { */ public required init(name: String, maxSize: UInt = 0) { self.maxSize = maxSize - let cacheName = name.capitalizedString - let paths = NSSearchPathForDirectoriesInDomains(.CachesDirectory, - NSSearchPathDomainMask.UserDomainMask, true) + let cacheName = name.capitalized + let paths = NSSearchPathForDirectoriesInDomains(.cachesDirectory, + FileManager.SearchPathDomainMask.userDomainMask, true) path = "\(paths.first!)/\(DiskStorage.prefix).\(cacheName)" - writeQueue = dispatch_queue_create("\(DiskStorage.prefix).\(cacheName).WriteQueue", - DISPATCH_QUEUE_SERIAL) - readQueue = dispatch_queue_create("\(DiskStorage.prefix).\(cacheName).ReadQueue", - DISPATCH_QUEUE_SERIAL) + writeQueue = DispatchQueue(label: "\(DiskStorage.prefix).\(cacheName).WriteQueue", + attributes: []) + readQueue = DispatchQueue(label: "\(DiskStorage.prefix).\(cacheName).ReadQueue", + attributes: []) } // MARK: - CacheAware @@ -55,26 +75,26 @@ public class DiskStorage: StorageAware { - Parameter expiry: Expiration date for the cached object - Parameter completion: Completion closure to be called when the task is done */ - public func add(key: String, object: T, expiry: Expiry = .Never, completion: (() -> Void)? = nil) { - dispatch_async(writeQueue) { [weak self] in + open func add(_ key: String, object: T, expiry: Expiry = .never, completion: (() -> Void)? = nil) { + writeQueue.async { [weak self] in guard let weakSelf = self else { completion?() return } - if !weakSelf.fileManager.fileExistsAtPath(weakSelf.path) { + if !weakSelf.fileManager.fileExists(atPath: weakSelf.path) { do { - try weakSelf.fileManager.createDirectoryAtPath(weakSelf.path, + try weakSelf.fileManager.createDirectory(atPath: weakSelf.path, withIntermediateDirectories: true, attributes: nil) } catch {} } do { let filePath = weakSelf.filePath(key) - weakSelf.fileManager.createFileAtPath(filePath, - contents: object.encode(), attributes: nil) + weakSelf.fileManager.createFile(atPath: filePath, + contents: object.encode() as Data?, attributes: nil) try weakSelf.fileManager.setAttributes( - [NSFileModificationDate : expiry.date], + [FileAttributeKey.modificationDate : expiry.date], ofItemAtPath: filePath) } catch {} @@ -88,21 +108,21 @@ public class DiskStorage: StorageAware { - Parameter key: Unique key to identify the object in the cache - Parameter completion: Completion closure returns object or nil */ - public func object(key: String, completion: (object: T?) -> Void) { - dispatch_async(readQueue) { [weak self] in + open func object(_ key: String, completion: @escaping (_ object: T?) -> Void) { + readQueue.async { [weak self] in guard let weakSelf = self else { - completion(object: nil) + completion(nil) return } let filePath = weakSelf.filePath(key) var cachedObject: T? - if let data = NSData(contentsOfFile: filePath) { + if let data = try? Data(contentsOf: URL(fileURLWithPath: filePath)) { cachedObject = T.decode(data) as? T } - completion(object: cachedObject) + completion(cachedObject) } } @@ -112,15 +132,15 @@ public class DiskStorage: StorageAware { - Parameter key: Unique key to identify the object in the cache - Parameter completion: Completion closure to be called when the task is done */ - public func remove(key: String, completion: (() -> Void)? = nil) { - dispatch_async(writeQueue) { [weak self] in + open func remove(_ key: String, completion: (() -> Void)? = nil) { + writeQueue.async { [weak self] in guard let weakSelf = self else { completion?() return } do { - try weakSelf.fileManager.removeItemAtPath(weakSelf.filePath(key)) + try weakSelf.fileManager.removeItem(atPath: weakSelf.filePath(key)) } catch {} completion?() @@ -133,20 +153,20 @@ public class DiskStorage: StorageAware { - Parameter key: Unique key to identify the object in the cache - Parameter completion: Completion closure to be called when the task is done */ - public func removeIfExpired(key: String, completion: (() -> Void)?) { + open func removeIfExpired(_ key: String, completion: (() -> Void)?) { let path = filePath(key) - dispatch_async(writeQueue) { [weak self] in + writeQueue.async { [weak self] in guard let weakSelf = self else { completion?() return } do { - let attributes = try weakSelf.fileManager.attributesOfItemAtPath(path) - if let expiryDate = attributes[NSFileModificationDate] as? NSDate - where expiryDate.inThePast { - try weakSelf.fileManager.removeItemAtPath(weakSelf.filePath(key)) + let attributes = try weakSelf.fileManager.attributesOfItem(atPath: path) + if let expiryDate = attributes[FileAttributeKey.modificationDate] as? Date + , expiryDate.inThePast { + try weakSelf.fileManager.removeItem(atPath: weakSelf.filePath(key)) } } catch {} @@ -159,15 +179,15 @@ public class DiskStorage: StorageAware { - Parameter completion: Completion closure to be called when the task is done */ - public func clear(completion: (() -> Void)? = nil) { - dispatch_async(writeQueue) { [weak self] in + open func clear(_ completion: (() -> Void)? = nil) { + writeQueue.async { [weak self] in guard let weakSelf = self else { completion?() return } do { - try weakSelf.fileManager.removeItemAtPath(weakSelf.path) + try weakSelf.fileManager.removeItem(atPath: weakSelf.path) } catch {} completion?() @@ -179,41 +199,41 @@ public class DiskStorage: StorageAware { - Parameter completion: Completion closure to be called when the task is done */ - public func clearExpired(completion: (() -> Void)? = nil) { - dispatch_async(writeQueue) { [weak self] in + open func clearExpired(_ completion: (() -> Void)? = nil) { + writeQueue.async { [weak self] in guard let weakSelf = self else { completion?() return } - let URL = NSURL(fileURLWithPath: weakSelf.path) - let resourceKeys = [NSURLIsDirectoryKey, NSURLContentModificationDateKey, NSURLTotalFileAllocatedSizeKey] - var objects = [(URL: NSURL, resourceValues: [NSObject: AnyObject])]() - var URLsToDelete = [NSURL]() + let URL = Foundation.URL(fileURLWithPath: weakSelf.path) + let resourceKeys = [URLResourceKey.isDirectoryKey, URLResourceKey.contentModificationDateKey, URLResourceKey.totalFileAllocatedSizeKey] + var objects: [(URL: Foundation.URL, resourceValues: [AnyHashable: Any])] = [] + var URLsToDelete: [Foundation.URL] = [] var totalSize: UInt = 0 - guard let fileEnumerator = weakSelf.fileManager.enumeratorAtURL(URL, includingPropertiesForKeys: resourceKeys, - options: .SkipsHiddenFiles, errorHandler: nil), URLs = fileEnumerator.allObjects as? [NSURL] else { + guard let fileEnumerator = weakSelf.fileManager.enumerator(at: URL, includingPropertiesForKeys: resourceKeys, + options: .skipsHiddenFiles, errorHandler: nil), let URLs = fileEnumerator.allObjects as? [Foundation.URL] else { completion?() return } for fileURL in URLs { do { - let resourceValues = try fileURL.resourceValuesForKeys(resourceKeys) + let resourceValues = try (fileURL as NSURL).resourceValues(forKeys: resourceKeys) - guard (resourceValues[NSURLIsDirectoryKey] as? NSNumber)?.boolValue == false else { + guard (resourceValues[URLResourceKey.isDirectoryKey] as? NSNumber)?.boolValue == false else { continue } - if let expiryDate = resourceValues[NSURLContentModificationDateKey] as? NSDate - where expiryDate.inThePast { + if let expiryDate = resourceValues[URLResourceKey.contentModificationDateKey] as? Date + , expiryDate.inThePast { URLsToDelete.append(fileURL) continue } - if let fileSize = resourceValues[NSURLTotalFileAllocatedSizeKey] as? NSNumber { - totalSize += fileSize.unsignedLongValue + if let fileSize = resourceValues[URLResourceKey.totalFileAllocatedSizeKey] as? NSNumber { + totalSize += fileSize.uintValue objects.append((URL: fileURL, resourceValues: resourceValues)) } } catch {} @@ -221,26 +241,26 @@ public class DiskStorage: StorageAware { for fileURL in URLsToDelete { do { - try weakSelf.fileManager.removeItemAtURL(fileURL) + try weakSelf.fileManager.removeItem(at: fileURL) } catch {} } if weakSelf.maxSize > 0 && totalSize > weakSelf.maxSize { let targetSize = weakSelf.maxSize / 2 - let sortedFiles = objects.sort { - let time1 = ($0.resourceValues[NSURLContentModificationDateKey] as? NSDate)?.timeIntervalSince1970 - let time2 = ($1.resourceValues[NSURLContentModificationDateKey] as? NSDate)?.timeIntervalSince1970 + let sortedFiles = objects.sorted { + let time1 = ($0.resourceValues[URLResourceKey.contentModificationDateKey] as? Date)?.timeIntervalSince1970 + let time2 = ($1.resourceValues[URLResourceKey.contentModificationDateKey] as? Date)?.timeIntervalSince1970 return time1 > time2 } for file in sortedFiles { do { - try weakSelf.fileManager.removeItemAtURL(file.URL) + try weakSelf.fileManager.removeItem(at: file.URL) } catch {} - if let fileSize = file.resourceValues[NSURLTotalFileAllocatedSizeKey] as? NSNumber { - totalSize -= fileSize.unsignedLongValue + if let fileSize = file.resourceValues[URLResourceKey.totalFileAllocatedSizeKey] as? NSNumber { + totalSize -= fileSize.uintValue } if totalSize < targetSize { @@ -261,13 +281,13 @@ public class DiskStorage: StorageAware { - Parameter key: Unique key to identify the object in the cache - Returns: A md5 or base64 string */ - func fileName(key: String) -> String { - if let digest = key.dataUsingEncoding(NSUTF8StringEncoding)?.md5() { + func fileName(_ key: String) -> String { + if let digest = key.data(using: String.Encoding.utf8)?.md5() { var string = "" - var byte: UInt8 = 0 + var byte: UnsafeMutablePointer - for i in 0 ..< digest.length { - digest.getBytes(&byte, range: NSRange(location: i, length: 1)) + for i in 0 ..< digest.count { + digest.copyBytes(to: byte, from: NSRange(location: i, length: 1)) string += String(format: "%02x", byte) } @@ -283,7 +303,7 @@ public class DiskStorage: StorageAware { - Parameter key: Unique key to identify the object in the cache - Returns: A string path based on key */ - func filePath(key: String) -> String { + func filePath(_ key: String) -> String { return "\(path)/\(fileName(key))" } } diff --git a/Source/Shared/Storage/MemoryStorage.swift b/Source/Shared/Storage/MemoryStorage.swift index 3259414a..f62ac065 100644 --- a/Source/Shared/Storage/MemoryStorage.swift +++ b/Source/Shared/Storage/MemoryStorage.swift @@ -3,25 +3,25 @@ import Foundation /** Memory cache storage based on NSCache */ -public class MemoryStorage: StorageAware { +open class MemoryStorage: StorageAware { /// Domain prefix - public static let prefix = "no.hyper.Cache.Memory" + open static let prefix = "no.hyper.Cache.Memory" /// Storage root path - public var path: String { + open var path: String { return cache.name } /// Maximum size of the cache storage - public var maxSize: UInt + open var maxSize: UInt /// Memory cache instance - public let cache = NSCache() + open let cache = NSCache() /// Queue for write operations - public private(set) var writeQueue: dispatch_queue_t + open fileprivate(set) var writeQueue: DispatchQueue /// Queue for read operations - public private(set) var readQueue: dispatch_queue_t + open fileprivate(set) var readQueue: DispatchQueue // MARK: - Initialization @@ -36,9 +36,9 @@ public class MemoryStorage: StorageAware { cache.countLimit = Int(maxSize) cache.totalCostLimit = Int(maxSize) - cache.name = "\(MemoryStorage.prefix).\(name.capitalizedString)" - writeQueue = dispatch_queue_create("\(cache.name).WriteQueue", DISPATCH_QUEUE_SERIAL) - readQueue = dispatch_queue_create("\(cache.name).ReadQueue", DISPATCH_QUEUE_SERIAL) + cache.name = "\(MemoryStorage.prefix).\(name.capitalized)" + writeQueue = DispatchQueue(label: "\(cache.name).WriteQueue", attributes: []) + readQueue = DispatchQueue(label: "\(cache.name).ReadQueue", attributes: []) } // MARK: - CacheAware @@ -51,8 +51,8 @@ public class MemoryStorage: StorageAware { - Parameter expiry: Expiration date for the cached object - Parameter completion: Completion closure to be called when the task is done */ - public func add(key: String, object: T, expiry: Expiry = .Never, completion: (() -> Void)? = nil) { - dispatch_async(writeQueue) { [weak self] in + open func add(_ key: String, object: T, expiry: Expiry = .never, completion: (() -> Void)? = nil) { + writeQueue.async { [weak self] in guard let weakSelf = self else { completion?() return @@ -60,7 +60,7 @@ public class MemoryStorage: StorageAware { let capsule = Capsule(value: object, expiry: expiry) - weakSelf.cache.setObject(capsule, forKey: key) + weakSelf.cache.setObject(capsule, forKey: key as AnyObject) completion?() } } @@ -71,15 +71,15 @@ public class MemoryStorage: StorageAware { - Parameter key: Unique key to identify the object in the cache - Parameter completion: Completion closure returns object or nil */ - public func object(key: String, completion: (object: T?) -> Void) { - dispatch_async(readQueue) { [weak self] in + open func object(_ key: String, completion: @escaping (_ object: T?) -> Void) { + readQueue.async { [weak self] in guard let weakSelf = self else { - completion(object: nil) + completion(nil) return } - let capsule = weakSelf.cache.objectForKey(key) as? Capsule - completion(object: capsule?.value as? T) + let capsule = weakSelf.cache.object(forKey: key as AnyObject) as? Capsule + completion(capsule?.value as? T) if let capsule = capsule { weakSelf.removeIfExpired(key, capsule: capsule) @@ -93,14 +93,14 @@ public class MemoryStorage: StorageAware { - Parameter key: Unique key to identify the object in the cache - Parameter completion: Completion closure to be called when the task is done */ - public func remove(key: String, completion: (() -> Void)? = nil) { - dispatch_async(writeQueue) { [weak self] in + open func remove(_ key: String, completion: (() -> Void)? = nil) { + writeQueue.async { [weak self] in guard let weakSelf = self else { completion?() return } - weakSelf.cache.removeObjectForKey(key) + weakSelf.cache.removeObject(forKey: key as AnyObject) completion?() } } @@ -111,14 +111,14 @@ public class MemoryStorage: StorageAware { - Parameter key: Unique key to identify the object in the cache - Parameter completion: Completion closure to be called when the task is done */ - public func removeIfExpired(key: String, completion: (() -> Void)?) { - dispatch_async(writeQueue) { [weak self] in + open func removeIfExpired(_ key: String, completion: (() -> Void)?) { + writeQueue.async { [weak self] in guard let weakSelf = self else { completion?() return } - if let capsule = weakSelf.cache.objectForKey(key) as? Capsule { + if let capsule = weakSelf.cache.object(forKey: key as AnyObject) as? Capsule { weakSelf.removeIfExpired(key, capsule: capsule, completion: completion) } else { completion?() @@ -131,8 +131,8 @@ public class MemoryStorage: StorageAware { - Parameter completion: Completion closure to be called when the task is done */ - public func clear(completion: (() -> Void)? = nil) { - dispatch_async(writeQueue) { [weak self] in + open func clear(_ completion: (() -> Void)? = nil) { + writeQueue.async { [weak self] in guard let weakSelf = self else { completion?() return @@ -148,7 +148,7 @@ public class MemoryStorage: StorageAware { - Parameter completion: Completion closure to be called when the task is done */ - public func clearExpired(completion: (() -> Void)? = nil) { + open func clearExpired(_ completion: (() -> Void)? = nil) { clear(completion) } @@ -161,7 +161,7 @@ public class MemoryStorage: StorageAware { - Parameter capsule: cached object wrapper - Parameter completion: Completion closure to be called when the task is done */ - func removeIfExpired(key: String, capsule: Capsule, completion: (() -> Void)? = nil) { + func removeIfExpired(_ key: String, capsule: Capsule, completion: (() -> Void)? = nil) { if capsule.expired { remove(key, completion: completion) } else { diff --git a/Source/Shared/Storage/StorageAware.swift b/Source/Shared/Storage/StorageAware.swift index 90996df4..6694846b 100644 --- a/Source/Shared/Storage/StorageAware.swift +++ b/Source/Shared/Storage/StorageAware.swift @@ -13,7 +13,7 @@ public protocol CacheAware { - Parameter expiry: Expiration date for the cached object - Parameter completion: Completion closure to be called when the task is done */ - func add(key: String, object: T, expiry: Expiry, completion: (() -> Void)?) + func add(_ key: String, object: T, expiry: Expiry, completion: (() -> Void)?) /** Tries to retrieve the object from the cache. @@ -21,7 +21,7 @@ public protocol CacheAware { - Parameter key: Unique key to identify the object in the cache - Parameter completion: Completion closure returns object or nil */ - func object(key: String, completion: (object: T?) -> Void) + func object(_ key: String, completion: @escaping (_ object: T?) -> Void) /** Removes the object from the cache by the given key. @@ -29,7 +29,7 @@ public protocol CacheAware { - Parameter key: Unique key to identify the object in the cache - Parameter completion: Completion closure to be called when the task is done */ - func remove(key: String, completion: (() -> Void)?) + func remove(_ key: String, completion: (() -> Void)?) /** Removes the object from the cache if it's expired. @@ -37,21 +37,21 @@ public protocol CacheAware { - Parameter key: Unique key to identify the object in the cache - Parameter completion: Completion closure to be called when the task is done */ - func removeIfExpired(key: String, completion: (() -> Void)?) + func removeIfExpired(_ key: String, completion: (() -> Void)?) /** Clears the cache storage. - Parameter completion: Completion closure to be called when the task is done */ - func clear(completion: (() -> Void)?) + func clear(_ completion: (() -> Void)?) /** Clears all expired objects. - Parameter completion: Completion closure to be called when the task is done */ - func clearExpired(completion: (() -> Void)?) + func clearExpired(_ completion: (() -> Void)?) } /** @@ -66,9 +66,9 @@ public protocol StorageAware: CacheAware { /// Maximum size of the cache storage var maxSize: UInt { get set } /// Queue for write operations - var writeQueue: dispatch_queue_t { get } + var writeQueue: DispatchQueue { get } /// Queue for read operations - var readQueue: dispatch_queue_t { get } + var readQueue: DispatchQueue { get } /** Storage initialization. diff --git a/Source/Shared/Storage/StorageFactory.swift b/Source/Shared/Storage/StorageFactory.swift index f6237cef..c9529495 100644 --- a/Source/Shared/Storage/StorageFactory.swift +++ b/Source/Shared/Storage/StorageFactory.swift @@ -1,19 +1,19 @@ /** A place to register and retrieve a cache storage by type. */ -public class StorageFactory { +open class StorageFactory { /// Default storage type - private static var DefaultStorage: StorageAware.Type = MemoryStorage.self + fileprivate static var DefaultStorage: StorageAware.Type = MemoryStorage.self /// Dictionary of default storages - private static var defaultStorages: [String: StorageAware.Type] = [ - StorageKind.Memory.name : MemoryStorage.self, - StorageKind.Disk.name : DiskStorage.self + fileprivate static var defaultStorages: [String: StorageAware.Type] = [ + StorageKind.memory.name : MemoryStorage.self, + StorageKind.disk.name : DiskStorage.self ] /// Dictionary of storages - private static var storages = defaultStorages + fileprivate static var storages = defaultStorages // MARK: - Factory @@ -23,7 +23,7 @@ public class StorageFactory { - Parameter kind: Storage kind - Parameter storage: StorageAware type */ - static func register(kind: StorageKind, storage: T.Type) { + static func register(_ kind: StorageKind, storage: T.Type) { storages[kind.name] = storage } @@ -35,7 +35,7 @@ public class StorageFactory { - Parameter maxSize: Maximum size of the cache storage - Returns: New storage */ - static func resolve(name: String, kind: StorageKind, maxSize: UInt = 0) -> StorageAware { + static func resolve(_ name: String, kind: StorageKind, maxSize: UInt = 0) -> StorageAware { let StorageType: StorageAware.Type = storages[kind.name] ?? DefaultStorage return StorageType.init(name: name, maxSize: maxSize) } diff --git a/Source/iOS/Extensions/UIImage+Cache.swift b/Source/iOS/Extensions/UIImage+Cache.swift index 83d7a94b..8bcdfd0a 100644 --- a/Source/iOS/Extensions/UIImage+Cache.swift +++ b/Source/iOS/Extensions/UIImage+Cache.swift @@ -15,7 +15,7 @@ extension UIImage: Cachable { - Parameter data: Data to decode from - Returns: An optional share type */ - public static func decode(data: NSData) -> CacheType? { + public static func decode(_ data: Data) -> CacheType? { let image = UIImage(data: data) return image } @@ -25,7 +25,7 @@ extension UIImage: Cachable { - Returns: Optional NSData */ - public func encode() -> NSData? { + public func encode() -> Data? { return hasAlpha ? UIImagePNGRepresentation(self) : UIImageJPEGRepresentation(self, 1.0) @@ -44,10 +44,11 @@ extension UIImage { */ var hasAlpha: Bool { let result: Bool - let alpha = CGImageGetAlphaInfo(CGImage) + + guard let alpha = cgImage?.alphaInfo else { return false } switch alpha { - case .None, .NoneSkipFirst, .NoneSkipLast: + case .none, .noneSkipFirst, .noneSkipLast: result = false default: result = true diff --git a/Source/iOS/HybridCache.swift b/Source/iOS/HybridCache.swift index cc462232..e62c7d8e 100644 --- a/Source/iOS/HybridCache.swift +++ b/Source/iOS/HybridCache.swift @@ -5,7 +5,7 @@ import UIKit Cachable protocol. It's two layered cache (with front and back storages), as well as Cache. Subscribes to system notifications to clear expired cached objects. */ -public class HybridCache: BasicHybridCache { +open class HybridCache: BasicHybridCache { // MARK: - Inititalization @@ -18,21 +18,21 @@ public class HybridCache: BasicHybridCache { public override init(name: String, config: Config = Config.defaultConfig) { super.init(name: name, config: config) - let notificationCenter = NSNotificationCenter.defaultCenter() + let notificationCenter = NotificationCenter.default notificationCenter.addObserver(self, selector: #selector(HybridCache.applicationDidReceiveMemoryWarning), - name: UIApplicationDidReceiveMemoryWarningNotification, object: nil) + name: NSNotification.Name.UIApplicationDidReceiveMemoryWarning, object: nil) notificationCenter.addObserver(self, selector: #selector(HybridCache.applicationWillTerminate), - name: UIApplicationWillTerminateNotification, object: nil) + name: NSNotification.Name.UIApplicationWillTerminate, object: nil) notificationCenter.addObserver(self, selector: #selector(HybridCache.applicationDidEnterBackground), - name: UIApplicationDidEnterBackgroundNotification, object: nil) + name: NSNotification.Name.UIApplicationDidEnterBackground, object: nil) } /** Removes notification center observer. */ deinit { - NSNotificationCenter.defaultCenter().removeObserver(self) + NotificationCenter.default.removeObserver(self) } // MARK: - Notifications @@ -55,21 +55,21 @@ public class HybridCache: BasicHybridCache { Clears expired cache items when the app enters background. */ func applicationDidEnterBackground() { - let application = UIApplication.sharedApplication() + let application = UIApplication.shared var backgroundTask: UIBackgroundTaskIdentifier? - backgroundTask = application.beginBackgroundTaskWithExpirationHandler { [weak self] in - guard let weakSelf = self, backgroundTask = backgroundTask else { return } + backgroundTask = application.beginBackgroundTask (expirationHandler: { [weak self] in + guard let weakSelf = self, let backgroundTask = backgroundTask else { return } var mutableBackgroundTask = backgroundTask weakSelf.endBackgroundTask(&mutableBackgroundTask) - } + }) backStorage.clearExpired { [weak self] in - guard let weakSelf = self, backgroundTask = backgroundTask else { return } + guard let weakSelf = self, let backgroundTask = backgroundTask else { return } var mutableBackgroundTask = backgroundTask - dispatch_async(dispatch_get_main_queue()) { + DispatchQueue.main.async { weakSelf.endBackgroundTask(&mutableBackgroundTask) } } @@ -79,8 +79,8 @@ public class HybridCache: BasicHybridCache { Ends given background task. - Parameter task: A UIBackgroundTaskIdentifier */ - func endBackgroundTask(inout task: UIBackgroundTaskIdentifier) { - UIApplication.sharedApplication().endBackgroundTask(task) + func endBackgroundTask(_ task: inout UIBackgroundTaskIdentifier) { + UIApplication.shared.endBackgroundTask(task) task = UIBackgroundTaskInvalid } } diff --git a/Tests/iOS/Helpers/SpecHelper.swift b/Tests/iOS/Helpers/SpecHelper.swift index 45cea494..9e70ee58 100644 --- a/Tests/iOS/Helpers/SpecHelper.swift +++ b/Tests/iOS/Helpers/SpecHelper.swift @@ -6,22 +6,22 @@ struct SpecHelper { return User(firstName: "John", lastName: "Snow") } - static func data(length : Int) -> NSData { - var buffer = [UInt8](count:length, repeatedValue:0) - return NSData(bytes:&buffer, length: length) + static func data(_ length : Int) -> Data { + var buffer = [UInt8](repeating: 0, count: length) + return Data(bytes: UnsafePointer(&buffer), count: length) } - static func image(color: UIColor = UIColor.redColor(), + static func image(_ color: UIColor = UIColor.red, size: CGSize = CGSize(width: 1, height: 1), opaque: Bool = false) -> UIImage { UIGraphicsBeginImageContextWithOptions(size, opaque, 0) let context = UIGraphicsGetCurrentContext() - CGContextSetFillColorWithColor(context, color.CGColor) - CGContextFillRect(context, CGRectMake(0, 0, size.width, size.height)) + context?.setFillColor(color.cgColor) + context?.fill(CGRect(x: 0, y: 0, width: size.width, height: size.height)) let image = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() - return image + return image! } } diff --git a/Tests/iOS/Helpers/UIImage+CacheTests.swift b/Tests/iOS/Helpers/UIImage+CacheTests.swift index 86bd86e7..dbff9f2e 100644 --- a/Tests/iOS/Helpers/UIImage+CacheTests.swift +++ b/Tests/iOS/Helpers/UIImage+CacheTests.swift @@ -2,23 +2,23 @@ import UIKit extension UIImage { - func isEqualToImage(image: UIImage) -> Bool { + func isEqualToImage(_ image: UIImage) -> Bool { let data = normalizedData() - return data.isEqualToData(image.normalizedData()) + return (data == image.normalizedData()) } - func normalizedData() -> NSData { + func normalizedData() -> Data { let pixelSize = CGSize( width : size.width * scale, height : size.height * scale) UIGraphicsBeginImageContext(pixelSize) - drawInRect(CGRect(x: 0, y: 0, width: pixelSize.width, + draw(in: CGRect(x: 0, y: 0, width: pixelSize.width, height: pixelSize.height)) let drawnImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() - return CGDataProviderCopyData(CGImageGetDataProvider(drawnImage.CGImage))! + return drawnImage!.cgImage!.dataProvider!.data! as Data } } diff --git a/Tests/iOS/Helpers/User.swift b/Tests/iOS/Helpers/User.swift index 040251ee..79575f44 100644 --- a/Tests/iOS/Helpers/User.swift +++ b/Tests/iOS/Helpers/User.swift @@ -16,7 +16,7 @@ extension User: Cachable { typealias CacheType = User - static func decode(data: NSData) -> CacheType? { + static func decode(_ data: Data) -> CacheType? { var object: User? do { @@ -26,8 +26,8 @@ extension User: Cachable { return object } - func encode() -> NSData? { - var data: NSData? + func encode() -> Data? { + var data: Data? do { data = try DefaultCacheConverter().encode(self) diff --git a/Tests/iOS/Specs/CacheSpec.swift b/Tests/iOS/Specs/CacheSpec.swift index 68c60049..d431445e 100644 --- a/Tests/iOS/Specs/CacheSpec.swift +++ b/Tests/iOS/Specs/CacheSpec.swift @@ -42,9 +42,9 @@ class CacheSpec: QuickSpec { describe("#add") { it("saves an object to memory and disk") { - let expectation1 = self.expectationWithDescription("Save Expectation") - let expectation2 = self.expectationWithDescription("Save To Memory Expectation") - let expectation3 = self.expectationWithDescription("Save To Disk Expectation") + let expectation1 = self.expectation(withDescription: "Save Expectation") + let expectation2 = self.expectation(withDescription: "Save To Memory Expectation") + let expectation3 = self.expectation(withDescription: "Save To Disk Expectation") cache.add(key, object: object) { cache.object(key) { (receivedObject: User?) in @@ -63,13 +63,13 @@ class CacheSpec: QuickSpec { } } - self.waitForExpectationsWithTimeout(8.0, handler:nil) + self.waitForExpectations(withTimeout: 8.0, handler:nil) } } describe("#object") { it("resolves cached object") { - let expectation = self.expectationWithDescription("Object Expectation") + let expectation = self.expectation(withDescription: "Object Expectation") cache.add(key, object: object) { cache.object(key) { (receivedObject: User?) in @@ -79,15 +79,15 @@ class CacheSpec: QuickSpec { } } - self.waitForExpectationsWithTimeout(4.0, handler:nil) + self.waitForExpectations(withTimeout: 4.0, handler:nil) } } describe("#remove") { it("removes cached object from memory and disk") { - let expectation1 = self.expectationWithDescription("Remove Expectation") - let expectation2 = self.expectationWithDescription("Remove From Memory Expectation") - let expectation3 = self.expectationWithDescription("Remove From Disk Expectation") + let expectation1 = self.expectation(withDescription: "Remove Expectation") + let expectation2 = self.expectation(withDescription: "Remove From Memory Expectation") + let expectation3 = self.expectation(withDescription: "Remove From Disk Expectation") cache.add(key, object: object) @@ -108,15 +108,15 @@ class CacheSpec: QuickSpec { } } - self.waitForExpectationsWithTimeout(8.0, handler:nil) + self.waitForExpectations(withTimeout: 8.0, handler:nil) } } describe("#clear") { it("clears memory and disk cache") { - let expectation1 = self.expectationWithDescription("Clear Expectation") - let expectation2 = self.expectationWithDescription("Clear Memory Expectation") - let expectation3 = self.expectationWithDescription("Clear Disk Expectation") + let expectation1 = self.expectation(withDescription: "Clear Expectation") + let expectation2 = self.expectation(withDescription: "Clear Memory Expectation") + let expectation3 = self.expectation(withDescription: "Clear Disk Expectation") cache.add(key, object: object) @@ -137,7 +137,7 @@ class CacheSpec: QuickSpec { } } - self.waitForExpectationsWithTimeout(8.0, handler:nil) + self.waitForExpectations(withTimeout: 8.0, handler:nil) } } } diff --git a/Tests/iOS/Specs/DataStructures/CapsuleSpec.swift b/Tests/iOS/Specs/DataStructures/CapsuleSpec.swift index 973a5330..a49626de 100644 --- a/Tests/iOS/Specs/DataStructures/CapsuleSpec.swift +++ b/Tests/iOS/Specs/DataStructures/CapsuleSpec.swift @@ -11,14 +11,14 @@ class CapsuleSpec: QuickSpec { describe("#expired") { it("is not expired") { - let date = NSDate(timeInterval: 100000, sinceDate: NSDate()) + let date = Date(timeInterval: 100000, since: Date()) capsule = Capsule(value: object, expiry: .Date(date)) expect(capsule.expired).to(beFalse()) } it("is expired") { - let date = NSDate(timeInterval: -100000, sinceDate: NSDate()) + let date = Date(timeInterval: -100000, since: Date()) capsule = Capsule(value: object, expiry: .Date(date)) expect(capsule.expired).to(beTrue()) diff --git a/Tests/iOS/Specs/DataStructures/ExpirySpec.swift b/Tests/iOS/Specs/DataStructures/ExpirySpec.swift index b63c0d64..e9e7f4df 100644 --- a/Tests/iOS/Specs/DataStructures/ExpirySpec.swift +++ b/Tests/iOS/Specs/DataStructures/ExpirySpec.swift @@ -10,21 +10,21 @@ class ExpirySpec: QuickSpec { describe("#date") { it("returns date in the distant future") { - let date = NSDate(timeIntervalSince1970: 60 * 60 * 24 * 365 * 68) + let date = Date(timeIntervalSince1970: 60 * 60 * 24 * 365 * 68) expiry = .Never expect(expiry.date).to(equal(date)) } it("returns date by adding time interval") { - let date = NSDate().dateByAddingTimeInterval(1000) + let date = Date().addingTimeInterval(1000) expiry = .Seconds(1000) expect(expiry.date.timeIntervalSince1970) ≈ (date.timeIntervalSince1970, 0.01) } it("returns specified date") { - let date = NSDate().dateByAddingTimeInterval(1000) + let date = Date().addingTimeInterval(1000) expiry = .Date(date) expect(expiry.date).to(equal(date)) diff --git a/Tests/iOS/Specs/Extensions/JSON+CacheSpec.swift b/Tests/iOS/Specs/Extensions/JSON+CacheSpec.swift index 0474f81b..df7a21da 100644 --- a/Tests/iOS/Specs/Extensions/JSON+CacheSpec.swift +++ b/Tests/iOS/Specs/Extensions/JSON+CacheSpec.swift @@ -11,8 +11,8 @@ class JSONCacheSpec: QuickSpec { describe(".decode") { it("decodes a dictionary from NSData") { let object = ["key": "value"] - let data = try! NSJSONSerialization.dataWithJSONObject(object, - options: NSJSONWritingOptions()) + let data = try! JSONSerialization.data(withJSONObject: object, + options: JSONSerialization.WritingOptions()) let result = JSON.decode(data)! switch result { @@ -25,8 +25,8 @@ class JSONCacheSpec: QuickSpec { it("decodes an array from NSData") { let object = ["value1", "value2", "value3"] - let data = try! NSJSONSerialization.dataWithJSONObject(object, - options: NSJSONWritingOptions()) + let data = try! JSONSerialization.data(withJSONObject: object, + options: JSONSerialization.WritingOptions()) let result = JSON.decode(data)! switch result { @@ -42,8 +42,8 @@ class JSONCacheSpec: QuickSpec { describe("#encode") { it("encodes a dictionary to NSData") { let object = ["key": "value"] - let data = try! NSJSONSerialization.dataWithJSONObject(object, - options: NSJSONWritingOptions()) + let data = try! JSONSerialization.data(withJSONObject: object, + options: JSONSerialization.WritingOptions()) let result = JSON.Dictionary(object).encode() expect(result).to(equal(data)) @@ -51,8 +51,8 @@ class JSONCacheSpec: QuickSpec { it("encodes an array to NSData") { let object = ["value1", "value2", "value3"] - let data = try! NSJSONSerialization.dataWithJSONObject(object, - options: NSJSONWritingOptions()) + let data = try! JSONSerialization.data(withJSONObject: object, + options: JSONSerialization.WritingOptions()) let result = JSON.Array(object).encode() expect(result).to(equal(data)) diff --git a/Tests/iOS/Specs/Extensions/NSData+CacheSpec.swift b/Tests/iOS/Specs/Extensions/NSData+CacheSpec.swift index fa95798c..332c0e30 100644 --- a/Tests/iOS/Specs/Extensions/NSData+CacheSpec.swift +++ b/Tests/iOS/Specs/Extensions/NSData+CacheSpec.swift @@ -11,7 +11,7 @@ class NSDataCacheSpec: QuickSpec { describe(".decode") { it("decodes from NSData") { let data = SpecHelper.data(64) - let result = NSData.decode(data) + let result = Data.decode(data) expect(result).to(equal(data)) } diff --git a/Tests/iOS/Specs/Extensions/NSDate+CacheSpec.swift b/Tests/iOS/Specs/Extensions/NSDate+CacheSpec.swift index 7529881a..80db965c 100644 --- a/Tests/iOS/Specs/Extensions/NSDate+CacheSpec.swift +++ b/Tests/iOS/Specs/Extensions/NSDate+CacheSpec.swift @@ -9,13 +9,13 @@ class NSDateCacheSpec: QuickSpec { describe("#inThePast") { it("returns that date is not in the past") { - let date = NSDate(timeInterval: 100000, sinceDate: NSDate()) + let date = Date(timeInterval: 100000, since: Date()) expect(date.inThePast).to(beFalse()) } it("returns that date is in the past") { - let date = NSDate(timeInterval: -100000, sinceDate: NSDate()) + let date = Date(timeInterval: -100000, since: Date()) expect(date.inThePast).to(beTrue()) } @@ -24,9 +24,9 @@ class NSDateCacheSpec: QuickSpec { describe("Cachable") { describe(".decode") { it("decodes from NSData") { - let date = NSDate() - let data = NSKeyedArchiver.archivedDataWithRootObject(date) - let result = NSDate.decode(data) + let date = Date() + let data = NSKeyedArchiver.archivedData(withRootObject: date) + let result = Date.decode(data) expect(result).to(equal(date)) } @@ -34,8 +34,8 @@ class NSDateCacheSpec: QuickSpec { describe("#encode") { it("encodes to NSData") { - let date = NSDate() - let data = NSKeyedArchiver.archivedDataWithRootObject(date) + let date = Date() + let data = NSKeyedArchiver.archivedData(withRootObject: date) let result = data.encode() expect(result).to(equal(data)) diff --git a/Tests/iOS/Specs/Extensions/String+CacheSpec.swift b/Tests/iOS/Specs/Extensions/String+CacheSpec.swift index 8c206134..4e34fb04 100644 --- a/Tests/iOS/Specs/Extensions/String+CacheSpec.swift +++ b/Tests/iOS/Specs/Extensions/String+CacheSpec.swift @@ -26,7 +26,7 @@ class StringCacheSpec: QuickSpec { describe(".decode") { it("decodes from NSData") { let string = self.name - let data = string!.dataUsingEncoding(NSUTF8StringEncoding)! + let data = string!.data(using: String.Encoding.utf8)! let result = String.decode(data) expect(result).to(equal(string)) @@ -36,7 +36,7 @@ class StringCacheSpec: QuickSpec { describe("#encode") { it("encodes to NSData") { let string = self.name - let data = string!.dataUsingEncoding(NSUTF8StringEncoding)! + let data = string!.data(using: String.Encoding.utf8)! let result = string!.encode() expect(result).to(equal(data)) diff --git a/Tests/iOS/Specs/Library/DefaultCacheConverterSpec.swift b/Tests/iOS/Specs/Library/DefaultCacheConverterSpec.swift index 8c9578fa..9e5b1739 100644 --- a/Tests/iOS/Specs/Library/DefaultCacheConverterSpec.swift +++ b/Tests/iOS/Specs/Library/DefaultCacheConverterSpec.swift @@ -11,8 +11,8 @@ class DefaultCacheConverterSpec: QuickSpec { describe(".decode") { it("decodes string to NSData") { let data = object.encode()! - let pointer = UnsafeMutablePointer.alloc(1) - data.getBytes(pointer, length: data.length) + let pointer = UnsafeMutablePointer.allocate(capacity: 1) + (data as NSData).getBytes(pointer, length: data.count) let value = pointer.move() let result = try! DefaultCacheConverter().decode(data) @@ -24,8 +24,8 @@ class DefaultCacheConverterSpec: QuickSpec { describe(".encode") { it("decodes string to NSData") { - let data = withUnsafePointer(&object) { p in - NSData(bytes: p, length: sizeofValue(object)) + let data = withUnsafePointer(to: &object) { p in + Data(bytes: UnsafePointer(p), count: sizeofValue(object)) } let result = try! DefaultCacheConverter().encode(object) diff --git a/Tests/iOS/Specs/Storage/DiskStorageSpec.swift b/Tests/iOS/Specs/Storage/DiskStorageSpec.swift index 773e23f6..32c03523 100644 --- a/Tests/iOS/Specs/Storage/DiskStorageSpec.swift +++ b/Tests/iOS/Specs/Storage/DiskStorageSpec.swift @@ -11,7 +11,7 @@ class DiskStorageSpec: QuickSpec { let key = "youknownothing" let object = SpecHelper.user var storage: DiskStorage! - let fileManager = NSFileManager() + let fileManager = FileManager() beforeEach { storage = DiskStorage(name: name) @@ -25,8 +25,8 @@ class DiskStorageSpec: QuickSpec { describe("#path") { it("returns the correct path") { - let paths = NSSearchPathForDirectoriesInDomains(.CachesDirectory, - NSSearchPathDomainMask.UserDomainMask, true) + let paths = NSSearchPathForDirectoriesInDomains(.cachesDirectory, + FileManager.SearchPathDomainMask.userDomainMask, true) let path = "\(paths.first!)/\(DiskStorage.prefix).\(name.capitalizedString)" expect(storage.path).to(equal(path)) @@ -41,8 +41,8 @@ class DiskStorageSpec: QuickSpec { describe("#add") { it("creates cache directory") { - let expectation = self.expectationWithDescription( - "Create Cache Directory Expectation") + let expectation = self.expectation( + withDescription: "Create Cache Directory Expectation") storage.add(key, object: object) { let fileExist = fileManager.fileExistsAtPath(storage.path) @@ -50,11 +50,11 @@ class DiskStorageSpec: QuickSpec { expectation.fulfill() } - self.waitForExpectationsWithTimeout(2.0, handler:nil) + self.waitForExpectations(withTimeout: 2.0, handler:nil) } it("saves an object") { - let expectation = self.expectationWithDescription("Save Expectation") + let expectation = self.expectation(withDescription: "Save Expectation") storage.add(key, object: object) { let fileExist = fileManager.fileExistsAtPath(storage.filePath(key)) @@ -62,13 +62,13 @@ class DiskStorageSpec: QuickSpec { expectation.fulfill() } - self.waitForExpectationsWithTimeout(2.0, handler:nil) + self.waitForExpectations(withTimeout: 2.0, handler:nil) } } describe("#object") { it("resolves cached object") { - let expectation = self.expectationWithDescription("Object Expectation") + let expectation = self.expectation(withDescription: "Object Expectation") storage.add(key, object: object) { storage.object(key) { (receivedObject: User?) in @@ -78,13 +78,13 @@ class DiskStorageSpec: QuickSpec { } } - self.waitForExpectationsWithTimeout(2.0, handler:nil) + self.waitForExpectations(withTimeout: 2.0, handler:nil) } } describe("#remove") { it("removes cached object") { - let expectation = self.expectationWithDescription("Remove Expectation") + let expectation = self.expectation(withDescription: "Remove Expectation") storage.add(key, object: object) storage.remove(key) { @@ -93,14 +93,14 @@ class DiskStorageSpec: QuickSpec { expectation.fulfill() } - self.waitForExpectationsWithTimeout(2.0, handler:nil) + self.waitForExpectations(withTimeout: 2.0, handler:nil) } } describe("removeIfExpired") { it("removes expired object") { - let expectation = self.expectationWithDescription( - "Remove If Expired Expectation") + let expectation = self.expectation( + withDescription: "Remove If Expired Expectation") let expiry: Expiry = .Date(NSDate().dateByAddingTimeInterval(-100000)) storage.add(key, object: object, expiry: expiry) @@ -111,12 +111,12 @@ class DiskStorageSpec: QuickSpec { } } - self.waitForExpectationsWithTimeout(2.0, handler:nil) + self.waitForExpectations(withTimeout: 2.0, handler:nil) } it("don't remove not expired object") { - let expectation = self.expectationWithDescription( - "Don't Remove If Not Expired Expectation") + let expectation = self.expectation( + withDescription: "Don't Remove If Not Expired Expectation") storage.add(key, object: object) storage.removeIfExpired(key) { @@ -126,13 +126,13 @@ class DiskStorageSpec: QuickSpec { } } - self.waitForExpectationsWithTimeout(2.0, handler:nil) + self.waitForExpectations(withTimeout: 2.0, handler:nil) } } describe("#clear") { it("clears cache directory") { - let expectation = self.expectationWithDescription("Clear Expectation") + let expectation = self.expectation(withDescription: "Clear Expectation") storage.add(key, object: object) storage.clear() { @@ -141,16 +141,16 @@ class DiskStorageSpec: QuickSpec { expectation.fulfill() } - self.waitForExpectationsWithTimeout(2.0, handler:nil) + self.waitForExpectations(withTimeout: 2.0, handler:nil) } } describe("clearExpired") { it("removes expired objects") { - let expectation1 = self.expectationWithDescription( - "Clear If Expired Expectation") - let expectation2 = self.expectationWithDescription( - "Don't Clear If Not Expired Expectation") + let expectation1 = self.expectation( + withDescription: "Clear If Expired Expectation") + let expectation2 = self.expectation( + withDescription: "Don't Clear If Not Expired Expectation") let expiry1: Expiry = .Date(NSDate().dateByAddingTimeInterval(-100000)) let expiry2: Expiry = .Date(NSDate().dateByAddingTimeInterval(100000)) @@ -173,13 +173,13 @@ class DiskStorageSpec: QuickSpec { } } - self.waitForExpectationsWithTimeout(5.0, handler:nil) + self.waitForExpectations(withTimeout: 5.0, handler:nil) } } describe("#fileName") { it("returns a correct file name") { - if let digest = key.dataUsingEncoding(NSUTF8StringEncoding)?.md5() { + if let digest = key.data(using: String.Encoding.utf8)?.md5() { var string = "" var byte: UInt8 = 0 diff --git a/Tests/iOS/Specs/Storage/MemoryStorageSpec.swift b/Tests/iOS/Specs/Storage/MemoryStorageSpec.swift index 7d1904a8..2bb31d43 100644 --- a/Tests/iOS/Specs/Storage/MemoryStorageSpec.swift +++ b/Tests/iOS/Specs/Storage/MemoryStorageSpec.swift @@ -35,8 +35,8 @@ class MemoryStorageSpec: QuickSpec { describe("#add") { it("saves an object") { - let expectation = self.expectationWithDescription( - "Save Object Expectation") + let expectation = self.expectation( + withDescription: "Save Object Expectation") storage.add(key, object: object) { storage.object(key) { (receivedObject: User?) in @@ -45,14 +45,14 @@ class MemoryStorageSpec: QuickSpec { } } - self.waitForExpectationsWithTimeout(2.0, handler:nil) + self.waitForExpectations(withTimeout: 2.0, handler:nil) } } describe("#object") { it("resolves cached object") { - let expectation = self.expectationWithDescription( - "Object Expectation") + let expectation = self.expectation( + withDescription: "Object Expectation") storage.add(key, object: object) { storage.object(key) { (receivedObject: User?) in @@ -62,14 +62,14 @@ class MemoryStorageSpec: QuickSpec { } } - self.waitForExpectationsWithTimeout(2.0, handler:nil) + self.waitForExpectations(withTimeout: 2.0, handler:nil) } } describe("#remove") { it("removes cached object") { - let expectation = self.expectationWithDescription( - "Remove Expectation") + let expectation = self.expectation( + withDescription: "Remove Expectation") storage.add(key, object: object) storage.remove(key) { @@ -79,14 +79,14 @@ class MemoryStorageSpec: QuickSpec { } } - self.waitForExpectationsWithTimeout(2.0, handler:nil) + self.waitForExpectations(withTimeout: 2.0, handler:nil) } } describe("removeIfExpired") { it("removes expired object") { - let expectation = self.expectationWithDescription( - "Remove If Expired Expectation") + let expectation = self.expectation( + withDescription: "Remove If Expired Expectation") let expiry: Expiry = .Date(NSDate().dateByAddingTimeInterval(-100000)) storage.add(key, object: object, expiry: expiry) @@ -97,12 +97,12 @@ class MemoryStorageSpec: QuickSpec { } } - self.waitForExpectationsWithTimeout(4.0, handler:nil) + self.waitForExpectations(withTimeout: 4.0, handler:nil) } it("don't remove not expired object") { - let expectation = self.expectationWithDescription( - "Don't Remove If Not Expired Expectation") + let expectation = self.expectation( + withDescription: "Don't Remove If Not Expired Expectation") storage.add(key, object: object) storage.removeIfExpired(key) { @@ -112,14 +112,14 @@ class MemoryStorageSpec: QuickSpec { } } - self.waitForExpectationsWithTimeout(4.0, handler:nil) + self.waitForExpectations(withTimeout: 4.0, handler:nil) } } describe("#clear") { it("clears cache directory") { - let expectation = self.expectationWithDescription( - "Clear Expectation") + let expectation = self.expectation( + withDescription: "Clear Expectation") storage.add(key, object: object) storage.clear() { @@ -129,16 +129,16 @@ class MemoryStorageSpec: QuickSpec { } } - self.waitForExpectationsWithTimeout(2.0, handler:nil) + self.waitForExpectations(withTimeout: 2.0, handler:nil) } } describe("clearExpired") { it("removes expired objects") { - let expectation1 = self.expectationWithDescription( - "Clear Expired Expectation 1") - let expectation2 = self.expectationWithDescription( - "Clear Expired Expectation 2") + let expectation1 = self.expectation( + withDescription: "Clear Expired Expectation 1") + let expectation2 = self.expectation( + withDescription: "Clear Expired Expectation 2") let expiry1: Expiry = .Date(NSDate().dateByAddingTimeInterval(-100000)) let expiry2: Expiry = .Date(NSDate().dateByAddingTimeInterval(100000)) @@ -161,7 +161,7 @@ class MemoryStorageSpec: QuickSpec { } } - self.waitForExpectationsWithTimeout(5.0, handler:nil) + self.waitForExpectations(withTimeout: 5.0, handler:nil) } } } From 7f04c8b2fc7f6afec77fa79d923d4a697d79b3d2 Mon Sep 17 00:00:00 2001 From: Vadym Markov Date: Tue, 27 Sep 2016 12:59:48 +0200 Subject: [PATCH 2/7] Fix errors --- .swiftlint.yml | 2 + Cartfile | 2 +- Cartfile.private | 4 +- Cartfile.resolved | 6 +- Source/Shared/DataStructures/Capsule.swift | 4 +- .../Library/DefaultCacheConverter.swift | 6 +- Source/Shared/Storage/DiskStorage.swift | 77 +++++++++++-------- Source/Shared/Storage/MemoryStorage.swift | 2 +- .../DataStructures/StorageKindSpec.swift | 4 +- 9 files changed, 61 insertions(+), 46 deletions(-) diff --git a/.swiftlint.yml b/.swiftlint.yml index 59cabaa8..91bb9e7d 100644 --- a/.swiftlint.yml +++ b/.swiftlint.yml @@ -3,6 +3,8 @@ included: # paths to include during linting. `--path` is ignored if present. excluded: # paths to ignore during linting. Takes precedence over `included`. - Carthage - Pods +disabled_rules: + - type_name # configurable rules can be customized from this configuration file # binary rules can set their severity level diff --git a/Cartfile b/Cartfile index 4a0a6185..dfa8f09f 100644 --- a/Cartfile +++ b/Cartfile @@ -1 +1 @@ -github "krzyzanowskim/CryptoSwift" "swift3" +github "krzyzanowskim/CryptoSwift" diff --git a/Cartfile.private b/Cartfile.private index 0af895c0..e7e7d7dd 100644 --- a/Cartfile.private +++ b/Cartfile.private @@ -1,2 +1,2 @@ -github "Quick/Nimble" "master" -github "Quick/Quick" "swift-3.0" +github "Quick/Nimble" +github "Quick/Quick" diff --git a/Cartfile.resolved b/Cartfile.resolved index df9db97f..656862bf 100644 --- a/Cartfile.resolved +++ b/Cartfile.resolved @@ -1,3 +1,3 @@ -github "krzyzanowskim/CryptoSwift" "ed5119bde18d3dab33b2553b4c53ffef44b73594" -github "Quick/Nimble" "db706fc1d7130f6ac96c56aaf0e635fa3217fe57" -github "Quick/Quick" "1503fb019d72417d5d6e4fbebdbaa03c9e4a125f" +github "krzyzanowskim/CryptoSwift" "0.6.0" +github "Quick/Nimble" "v5.0.0" +github "Quick/Quick" "v0.10.0" diff --git a/Source/Shared/DataStructures/Capsule.swift b/Source/Shared/DataStructures/Capsule.swift index 5813658d..dcb7e394 100644 --- a/Source/Shared/DataStructures/Capsule.swift +++ b/Source/Shared/DataStructures/Capsule.swift @@ -7,7 +7,7 @@ import Foundation class Capsule: NSObject { /// Object to be cached - let value: Any + let object: Any /// Expiration date let expiryDate: Date @@ -25,7 +25,7 @@ class Capsule: NSObject { - Parameter expiry: Expiration date */ init(value: Any, expiry: Expiry) { - self.value = value + self.object = value self.expiryDate = expiry.date as Date } } diff --git a/Source/Shared/Library/DefaultCacheConverter.swift b/Source/Shared/Library/DefaultCacheConverter.swift index b78bda02..84e8dc1f 100644 --- a/Source/Shared/Library/DefaultCacheConverter.swift +++ b/Source/Shared/Library/DefaultCacheConverter.swift @@ -44,8 +44,10 @@ public struct DefaultCacheConverter { */ public func encode(_ value: T) throws -> Data { var value = value - return withUnsafePointer(to: &value) { p in - Data(bytes: UnsafePointer(p), count: MemoryLayout.size(ofValue: value)) + return withUnsafePointer(to: &value) { + $0.withMemoryRebound(to: UInt8.self, capacity: 1) { bytes in + Data(bytes: bytes, count: MemoryLayout.size(ofValue: value)) + } } } } diff --git a/Source/Shared/Storage/DiskStorage.swift b/Source/Shared/Storage/DiskStorage.swift index 4533dbee..73e79a27 100644 --- a/Source/Shared/Storage/DiskStorage.swift +++ b/Source/Shared/Storage/DiskStorage.swift @@ -1,6 +1,6 @@ import Foundation import CryptoSwift -fileprivate func < (lhs: T?, rhs: T?) -> Bool { +fileprivate func < (lhs: T?, rhs: T?) -> Bool { switch (lhs, rhs) { case let (l?, r?): return l < r @@ -11,7 +11,7 @@ fileprivate func < (lhs: T?, rhs: T?) -> Bool { } } -fileprivate func > (lhs: T?, rhs: T?) -> Bool { +fileprivate func > (lhs: T?, rhs: T?) -> Bool { switch (lhs, rhs) { case let (l?, r?): return l > r @@ -164,8 +164,8 @@ open class DiskStorage: StorageAware { do { let attributes = try weakSelf.fileManager.attributesOfItem(atPath: path) - if let expiryDate = attributes[FileAttributeKey.modificationDate] as? Date - , expiryDate.inThePast { + if let expiryDate = attributes[FileAttributeKey.modificationDate] as? Date, + expiryDate.inThePast { try weakSelf.fileManager.removeItem(atPath: weakSelf.filePath(key)) } } catch {} @@ -194,6 +194,8 @@ open class DiskStorage: StorageAware { } } + typealias ResourceObject = (url: Foundation.URL, resourceValues: [AnyHashable: Any]) + /** Clears all expired objects. @@ -207,8 +209,8 @@ open class DiskStorage: StorageAware { } let URL = Foundation.URL(fileURLWithPath: weakSelf.path) - let resourceKeys = [URLResourceKey.isDirectoryKey, URLResourceKey.contentModificationDateKey, URLResourceKey.totalFileAllocatedSizeKey] - var objects: [(URL: Foundation.URL, resourceValues: [AnyHashable: Any])] = [] + let resourceKeys: [URLResourceKey] = [.isDirectoryKey, .contentModificationDateKey, .totalFileAllocatedSizeKey] + var objects = [ResourceObject]() var URLsToDelete: [Foundation.URL] = [] var totalSize: UInt = 0 @@ -226,15 +228,15 @@ open class DiskStorage: StorageAware { continue } - if let expiryDate = resourceValues[URLResourceKey.contentModificationDateKey] as? Date - , expiryDate.inThePast { + if let expiryDate = resourceValues[URLResourceKey.contentModificationDateKey] as? Date, + expiryDate.inThePast { URLsToDelete.append(fileURL) continue } if let fileSize = resourceValues[URLResourceKey.totalFileAllocatedSizeKey] as? NSNumber { totalSize += fileSize.uintValue - objects.append((URL: fileURL, resourceValues: resourceValues)) + objects.append((url: fileURL, resourceValues: resourceValues)) } } catch {} } @@ -245,31 +247,43 @@ open class DiskStorage: StorageAware { } catch {} } - if weakSelf.maxSize > 0 && totalSize > weakSelf.maxSize { - let targetSize = weakSelf.maxSize / 2 + weakSelf.removeResourceObjects(objects, totalSize: totalSize) + completion?() + } + } - let sortedFiles = objects.sorted { - let time1 = ($0.resourceValues[URLResourceKey.contentModificationDateKey] as? Date)?.timeIntervalSince1970 - let time2 = ($1.resourceValues[URLResourceKey.contentModificationDateKey] as? Date)?.timeIntervalSince1970 - return time1 > time2 - } + /** + Removes expired resource objects. - for file in sortedFiles { - do { - try weakSelf.fileManager.removeItem(at: file.URL) - } catch {} + - Parameter objects: Resource objects to remove + - Parameter totalSize: Total size + */ + func removeResourceObjects(_ objects: [ResourceObject], totalSize: UInt) { + guard maxSize > 0 && totalSize > maxSize else { + return + } - if let fileSize = file.resourceValues[URLResourceKey.totalFileAllocatedSizeKey] as? NSNumber { - totalSize -= fileSize.uintValue - } + var totalSize = totalSize + let targetSize = maxSize / 2 - if totalSize < targetSize { - break - } - } + let sortedFiles = objects.sorted { + let time1 = ($0.resourceValues[URLResourceKey.contentModificationDateKey] as? Date)?.timeIntervalSince1970 + let time2 = ($1.resourceValues[URLResourceKey.contentModificationDateKey] as? Date)?.timeIntervalSince1970 + return time1 > time2 + } + + for file in sortedFiles { + do { + try fileManager.removeItem(at: file.url) + } catch {} + + if let fileSize = file.resourceValues[URLResourceKey.totalFileAllocatedSizeKey] as? NSNumber { + totalSize -= fileSize.uintValue } - completion?() + if totalSize < targetSize { + break + } } } @@ -284,11 +298,8 @@ open class DiskStorage: StorageAware { func fileName(_ key: String) -> String { if let digest = key.data(using: String.Encoding.utf8)?.md5() { var string = "" - var byte: UnsafeMutablePointer - - for i in 0 ..< digest.count { - digest.copyBytes(to: byte, from: NSRange(location: i, length: 1)) - string += String(format: "%02x", byte) + for byte in digest { + string += String(format:"%02x", byte) } return string diff --git a/Source/Shared/Storage/MemoryStorage.swift b/Source/Shared/Storage/MemoryStorage.swift index f62ac065..205883d9 100644 --- a/Source/Shared/Storage/MemoryStorage.swift +++ b/Source/Shared/Storage/MemoryStorage.swift @@ -79,7 +79,7 @@ open class MemoryStorage: StorageAware { } let capsule = weakSelf.cache.object(forKey: key as AnyObject) as? Capsule - completion(capsule?.value as? T) + completion(capsule?.object as? T) if let capsule = capsule { weakSelf.removeIfExpired(key, capsule: capsule) diff --git a/Tests/iOS/Specs/DataStructures/StorageKindSpec.swift b/Tests/iOS/Specs/DataStructures/StorageKindSpec.swift index 09ac155d..d62b4097 100644 --- a/Tests/iOS/Specs/DataStructures/StorageKindSpec.swift +++ b/Tests/iOS/Specs/DataStructures/StorageKindSpec.swift @@ -9,8 +9,8 @@ class StorageKindSpec: QuickSpec { describe("#name") { it("returns the correct name for default values") { - expect(StorageKind.Memory.name).to(equal("Memory")) - expect(StorageKind.Disk.name).to(equal("Disk")) + expect(StorageKind.memory.name).to(equal("Memory")) + expect(StorageKind.disk.name).to(equal("Disk")) } it("returns the correct name for custom values") { From b2664f8a08eeb34d616094abbfe0852db7b9a370 Mon Sep 17 00:00:00 2001 From: Vadym Markov Date: Tue, 27 Sep 2016 13:19:34 +0200 Subject: [PATCH 3/7] Migrate tests --- Source/Shared/DataStructures/Expiry.swift | 4 +- Source/Shared/DataStructures/JSON.swift | 12 ++-- Source/Shared/Library/SyncHybridCache.swift | 8 +-- Tests/iOS/Helpers/SpecHelper.swift | 4 +- Tests/iOS/Specs/CacheSpec.swift | 28 ++++---- Tests/iOS/Specs/ConfigSpec.swift | 6 +- .../Specs/DataStructures/CapsuleSpec.swift | 4 +- .../iOS/Specs/DataStructures/ExpirySpec.swift | 6 +- Tests/iOS/Specs/DataStructures/JSONSpec.swift | 4 +- .../DataStructures/StorageKindSpec.swift | 2 +- .../iOS/Specs/Extensions/JSON+CacheSpec.swift | 8 +-- .../Library/DefaultCacheConverterSpec.swift | 7 +- Tests/iOS/Specs/Storage/DiskStorageSpec.swift | 65 +++++++++---------- .../iOS/Specs/Storage/MemoryStorageSpec.swift | 46 ++++++------- .../Specs/Storage/StorageFactorySpec.swift | 22 +++---- 15 files changed, 107 insertions(+), 119 deletions(-) diff --git a/Source/Shared/DataStructures/Expiry.swift b/Source/Shared/DataStructures/Expiry.swift index a03e92a7..815ae722 100644 --- a/Source/Shared/DataStructures/Expiry.swift +++ b/Source/Shared/DataStructures/Expiry.swift @@ -9,7 +9,7 @@ public enum Expiry { /// Object will be expired in the specified amount of seconds case seconds(TimeInterval) /// Object will be expired on the specified date - case Date(Foundation.Date) + case date(Foundation.Date) /// Returns the appropriate date object public var date: Foundation.Date { @@ -21,7 +21,7 @@ public enum Expiry { result = Foundation.Date(timeIntervalSince1970: 60 * 60 * 24 * 365 * 68) case .seconds(let seconds): result = Foundation.Date().addingTimeInterval(seconds) - case .Date(let date): + case .date(let date): result = date } diff --git a/Source/Shared/DataStructures/JSON.swift b/Source/Shared/DataStructures/JSON.swift index 7bb081fa..6d07c786 100644 --- a/Source/Shared/DataStructures/JSON.swift +++ b/Source/Shared/DataStructures/JSON.swift @@ -5,19 +5,19 @@ import Foundation */ public enum JSON { /// JSON array - case array([AnyObject]) + case array([Any]) /// JSON dictionary - case dictionary([String : AnyObject]) + case dictionary([String : Any]) /// Converts value to AnyObject - public var object: AnyObject { - var result: AnyObject + public var object: Any { + var result: Any switch self { case .array(let object): - result = object as AnyObject + result = object as Any case .dictionary(let object): - result = object as AnyObject + result = object as Any } return result diff --git a/Source/Shared/Library/SyncHybridCache.swift b/Source/Shared/Library/SyncHybridCache.swift index 26a03b3c..27b95770 100644 --- a/Source/Shared/Library/SyncHybridCache.swift +++ b/Source/Shared/Library/SyncHybridCache.swift @@ -35,7 +35,7 @@ public struct SyncHybridCache { semaphore.signal() } - semaphore.wait(timeout: DispatchTime.distantFuture) + _ = semaphore.wait(timeout: DispatchTime.distantFuture) } /** @@ -54,7 +54,7 @@ public struct SyncHybridCache { semaphore.signal() } - semaphore.wait(timeout: DispatchTime.distantFuture) + _ = semaphore.wait(timeout: DispatchTime.distantFuture) return result } @@ -71,7 +71,7 @@ public struct SyncHybridCache { semaphore.signal() } - semaphore.wait(timeout: DispatchTime.distantFuture) + _ = semaphore.wait(timeout: DispatchTime.distantFuture) } /** @@ -84,6 +84,6 @@ public struct SyncHybridCache { semaphore.signal() } - semaphore.wait(timeout: DispatchTime.distantFuture) + _ = semaphore.wait(timeout: DispatchTime.distantFuture) } } diff --git a/Tests/iOS/Helpers/SpecHelper.swift b/Tests/iOS/Helpers/SpecHelper.swift index 9e70ee58..7d46e5ee 100644 --- a/Tests/iOS/Helpers/SpecHelper.swift +++ b/Tests/iOS/Helpers/SpecHelper.swift @@ -7,8 +7,8 @@ struct SpecHelper { } static func data(_ length : Int) -> Data { - var buffer = [UInt8](repeating: 0, count: length) - return Data(bytes: UnsafePointer(&buffer), count: length) + let buffer = [UInt8](repeating: 0, count: length) + return Data(bytes: buffer) } static func image(_ color: UIColor = UIColor.red, diff --git a/Tests/iOS/Specs/CacheSpec.swift b/Tests/iOS/Specs/CacheSpec.swift index d431445e..28658919 100644 --- a/Tests/iOS/Specs/CacheSpec.swift +++ b/Tests/iOS/Specs/CacheSpec.swift @@ -42,9 +42,9 @@ class CacheSpec: QuickSpec { describe("#add") { it("saves an object to memory and disk") { - let expectation1 = self.expectation(withDescription: "Save Expectation") - let expectation2 = self.expectation(withDescription: "Save To Memory Expectation") - let expectation3 = self.expectation(withDescription: "Save To Disk Expectation") + let expectation1 = self.expectation(description: "Save Expectation") + let expectation2 = self.expectation(description: "Save To Memory Expectation") + let expectation3 = self.expectation(description: "Save To Disk Expectation") cache.add(key, object: object) { cache.object(key) { (receivedObject: User?) in @@ -63,13 +63,13 @@ class CacheSpec: QuickSpec { } } - self.waitForExpectations(withTimeout: 8.0, handler:nil) + self.waitForExpectations(timeout: 8.0, handler:nil) } } describe("#object") { it("resolves cached object") { - let expectation = self.expectation(withDescription: "Object Expectation") + let expectation = self.expectation(description: "Object Expectation") cache.add(key, object: object) { cache.object(key) { (receivedObject: User?) in @@ -79,15 +79,15 @@ class CacheSpec: QuickSpec { } } - self.waitForExpectations(withTimeout: 4.0, handler:nil) + self.waitForExpectations(timeout: 4.0, handler:nil) } } describe("#remove") { it("removes cached object from memory and disk") { - let expectation1 = self.expectation(withDescription: "Remove Expectation") - let expectation2 = self.expectation(withDescription: "Remove From Memory Expectation") - let expectation3 = self.expectation(withDescription: "Remove From Disk Expectation") + let expectation1 = self.expectation(description: "Remove Expectation") + let expectation2 = self.expectation(description: "Remove From Memory Expectation") + let expectation3 = self.expectation(description: "Remove From Disk Expectation") cache.add(key, object: object) @@ -108,15 +108,15 @@ class CacheSpec: QuickSpec { } } - self.waitForExpectations(withTimeout: 8.0, handler:nil) + self.waitForExpectations(timeout: 8.0, handler:nil) } } describe("#clear") { it("clears memory and disk cache") { - let expectation1 = self.expectation(withDescription: "Clear Expectation") - let expectation2 = self.expectation(withDescription: "Clear Memory Expectation") - let expectation3 = self.expectation(withDescription: "Clear Disk Expectation") + let expectation1 = self.expectation(description: "Clear Expectation") + let expectation2 = self.expectation(description: "Clear Memory Expectation") + let expectation3 = self.expectation(description: "Clear Disk Expectation") cache.add(key, object: object) @@ -137,7 +137,7 @@ class CacheSpec: QuickSpec { } } - self.waitForExpectations(withTimeout: 8.0, handler:nil) + self.waitForExpectations(timeout: 8.0, handler:nil) } } } diff --git a/Tests/iOS/Specs/ConfigSpec.swift b/Tests/iOS/Specs/ConfigSpec.swift index e430d1a2..9800204a 100644 --- a/Tests/iOS/Specs/ConfigSpec.swift +++ b/Tests/iOS/Specs/ConfigSpec.swift @@ -11,9 +11,9 @@ class ConfigSpec: QuickSpec { it("returns the correct default config") { let config = Config.defaultConfig - expect(config.frontKind.name).to(equal(StorageKind.Memory.name)) - expect(config.backKind.name).to(equal(StorageKind.Disk.name)) - expect(config.expiry.date).to(equal(Expiry.Never.date)) + expect(config.frontKind.name).to(equal(StorageKind.memory.name)) + expect(config.backKind.name).to(equal(StorageKind.disk.name)) + expect(config.expiry.date).to(equal(Expiry.never.date)) expect(config.maxSize).to(equal(0)) } } diff --git a/Tests/iOS/Specs/DataStructures/CapsuleSpec.swift b/Tests/iOS/Specs/DataStructures/CapsuleSpec.swift index a49626de..78db96bf 100644 --- a/Tests/iOS/Specs/DataStructures/CapsuleSpec.swift +++ b/Tests/iOS/Specs/DataStructures/CapsuleSpec.swift @@ -12,14 +12,14 @@ class CapsuleSpec: QuickSpec { describe("#expired") { it("is not expired") { let date = Date(timeInterval: 100000, since: Date()) - capsule = Capsule(value: object, expiry: .Date(date)) + capsule = Capsule(value: object, expiry: .date(date)) expect(capsule.expired).to(beFalse()) } it("is expired") { let date = Date(timeInterval: -100000, since: Date()) - capsule = Capsule(value: object, expiry: .Date(date)) + capsule = Capsule(value: object, expiry: .date(date)) expect(capsule.expired).to(beTrue()) } diff --git a/Tests/iOS/Specs/DataStructures/ExpirySpec.swift b/Tests/iOS/Specs/DataStructures/ExpirySpec.swift index e9e7f4df..1eaf07c7 100644 --- a/Tests/iOS/Specs/DataStructures/ExpirySpec.swift +++ b/Tests/iOS/Specs/DataStructures/ExpirySpec.swift @@ -11,21 +11,21 @@ class ExpirySpec: QuickSpec { describe("#date") { it("returns date in the distant future") { let date = Date(timeIntervalSince1970: 60 * 60 * 24 * 365 * 68) - expiry = .Never + expiry = .never expect(expiry.date).to(equal(date)) } it("returns date by adding time interval") { let date = Date().addingTimeInterval(1000) - expiry = .Seconds(1000) + expiry = .seconds(1000) expect(expiry.date.timeIntervalSince1970) ≈ (date.timeIntervalSince1970, 0.01) } it("returns specified date") { let date = Date().addingTimeInterval(1000) - expiry = .Date(date) + expiry = .date(date) expect(expiry.date).to(equal(date)) } diff --git a/Tests/iOS/Specs/DataStructures/JSONSpec.swift b/Tests/iOS/Specs/DataStructures/JSONSpec.swift index 4c0fa948..aa8dffc4 100644 --- a/Tests/iOS/Specs/DataStructures/JSONSpec.swift +++ b/Tests/iOS/Specs/DataStructures/JSONSpec.swift @@ -9,8 +9,8 @@ class JSONSpec: QuickSpec { describe("#object") { it("returns the value") { - expect(JSON.Array(["Floppy"]).object is [AnyObject]).to(beTrue()) - expect(JSON.Dictionary(["Key": "Value"]).object is [String: AnyObject]).to(beTrue()) + expect(JSON.array(["Floppy"]).object is [AnyObject]).to(beTrue()) + expect(JSON.dictionary(["Key": "Value"]).object is [String: AnyObject]).to(beTrue()) } } } diff --git a/Tests/iOS/Specs/DataStructures/StorageKindSpec.swift b/Tests/iOS/Specs/DataStructures/StorageKindSpec.swift index d62b4097..59ce379f 100644 --- a/Tests/iOS/Specs/DataStructures/StorageKindSpec.swift +++ b/Tests/iOS/Specs/DataStructures/StorageKindSpec.swift @@ -14,7 +14,7 @@ class StorageKindSpec: QuickSpec { } it("returns the correct name for custom values") { - expect(StorageKind.Custom("Weirdo").name).to(equal("Weirdo")) + expect(StorageKind.custom("Weirdo").name).to(equal("Weirdo")) } } } diff --git a/Tests/iOS/Specs/Extensions/JSON+CacheSpec.swift b/Tests/iOS/Specs/Extensions/JSON+CacheSpec.swift index df7a21da..c555fc8d 100644 --- a/Tests/iOS/Specs/Extensions/JSON+CacheSpec.swift +++ b/Tests/iOS/Specs/Extensions/JSON+CacheSpec.swift @@ -16,7 +16,7 @@ class JSONCacheSpec: QuickSpec { let result = JSON.decode(data)! switch result { - case JSON.Dictionary(let dictionary): + case JSON.dictionary(let dictionary): expect(dictionary["key"] is String).to(beTrue()) expect(dictionary["key"] as? String).to(equal(object["key"])) default: break @@ -30,7 +30,7 @@ class JSONCacheSpec: QuickSpec { let result = JSON.decode(data)! switch result { - case JSON.Array(let array): + case JSON.array(let array): expect(array is [String]).to(beTrue()) expect(array.count).to(equal(3)) expect(array[0] as? String).to(equal(object[0])) @@ -44,7 +44,7 @@ class JSONCacheSpec: QuickSpec { let object = ["key": "value"] let data = try! JSONSerialization.data(withJSONObject: object, options: JSONSerialization.WritingOptions()) - let result = JSON.Dictionary(object).encode() + let result = JSON.dictionary(object as [String : AnyObject]).encode() expect(result).to(equal(data)) } @@ -53,7 +53,7 @@ class JSONCacheSpec: QuickSpec { let object = ["value1", "value2", "value3"] let data = try! JSONSerialization.data(withJSONObject: object, options: JSONSerialization.WritingOptions()) - let result = JSON.Array(object).encode() + let result = JSON.array(object as [AnyObject]).encode() expect(result).to(equal(data)) } diff --git a/Tests/iOS/Specs/Library/DefaultCacheConverterSpec.swift b/Tests/iOS/Specs/Library/DefaultCacheConverterSpec.swift index 9e5b1739..5a5169ba 100644 --- a/Tests/iOS/Specs/Library/DefaultCacheConverterSpec.swift +++ b/Tests/iOS/Specs/Library/DefaultCacheConverterSpec.swift @@ -24,9 +24,12 @@ class DefaultCacheConverterSpec: QuickSpec { describe(".encode") { it("decodes string to NSData") { - let data = withUnsafePointer(to: &object) { p in - Data(bytes: UnsafePointer(p), count: sizeofValue(object)) + let data = withUnsafePointer(to: &object) { + $0.withMemoryRebound(to: UInt8.self, capacity: 1) { bytes in + Data(bytes: bytes, count: MemoryLayout.size(ofValue: object)) + } } + let result = try! DefaultCacheConverter().encode(object) expect(result).to(equal(data)) diff --git a/Tests/iOS/Specs/Storage/DiskStorageSpec.swift b/Tests/iOS/Specs/Storage/DiskStorageSpec.swift index 32c03523..155ae7dc 100644 --- a/Tests/iOS/Specs/Storage/DiskStorageSpec.swift +++ b/Tests/iOS/Specs/Storage/DiskStorageSpec.swift @@ -19,7 +19,7 @@ class DiskStorageSpec: QuickSpec { afterEach { do { - try fileManager.removeItemAtPath(storage.path) + try fileManager.removeItem(atPath: storage.path) } catch {} } @@ -27,7 +27,7 @@ class DiskStorageSpec: QuickSpec { it("returns the correct path") { let paths = NSSearchPathForDirectoriesInDomains(.cachesDirectory, FileManager.SearchPathDomainMask.userDomainMask, true) - let path = "\(paths.first!)/\(DiskStorage.prefix).\(name.capitalizedString)" + let path = "\(paths.first!)/\(DiskStorage.prefix).\(name.capitalized)" expect(storage.path).to(equal(path)) } @@ -41,34 +41,33 @@ class DiskStorageSpec: QuickSpec { describe("#add") { it("creates cache directory") { - let expectation = self.expectation( - withDescription: "Create Cache Directory Expectation") + let expectation = self.expectation(description: "Create Cache Directory Expectation") storage.add(key, object: object) { - let fileExist = fileManager.fileExistsAtPath(storage.path) + let fileExist = fileManager.fileExists(atPath: storage.path) expect(fileExist).to(beTrue()) expectation.fulfill() } - self.waitForExpectations(withTimeout: 2.0, handler:nil) + self.waitForExpectations(timeout: 2.0, handler:nil) } it("saves an object") { - let expectation = self.expectation(withDescription: "Save Expectation") + let expectation = self.expectation(description: "Save Expectation") storage.add(key, object: object) { - let fileExist = fileManager.fileExistsAtPath(storage.filePath(key)) + let fileExist = fileManager.fileExists(atPath: storage.filePath(key)) expect(fileExist).to(beTrue()) expectation.fulfill() } - self.waitForExpectations(withTimeout: 2.0, handler:nil) + self.waitForExpectations(timeout: 2.0, handler:nil) } } describe("#object") { it("resolves cached object") { - let expectation = self.expectation(withDescription: "Object Expectation") + let expectation = self.expectation(description: "Object Expectation") storage.add(key, object: object) { storage.object(key) { (receivedObject: User?) in @@ -78,30 +77,29 @@ class DiskStorageSpec: QuickSpec { } } - self.waitForExpectations(withTimeout: 2.0, handler:nil) + self.waitForExpectations(timeout: 2.0, handler:nil) } } describe("#remove") { it("removes cached object") { - let expectation = self.expectation(withDescription: "Remove Expectation") + let expectation = self.expectation(description: "Remove Expectation") storage.add(key, object: object) storage.remove(key) { - let fileExist = fileManager.fileExistsAtPath(storage.filePath(key)) + let fileExist = fileManager.fileExists(atPath: storage.filePath(key)) expect(fileExist).to(beFalse()) expectation.fulfill() } - self.waitForExpectations(withTimeout: 2.0, handler:nil) + self.waitForExpectations(timeout: 2.0, handler:nil) } } describe("removeIfExpired") { it("removes expired object") { - let expectation = self.expectation( - withDescription: "Remove If Expired Expectation") - let expiry: Expiry = .Date(NSDate().dateByAddingTimeInterval(-100000)) + let expectation = self.expectation(description: "Remove If Expired Expectation") + let expiry: Expiry = .date(Date().addingTimeInterval(-100000)) storage.add(key, object: object, expiry: expiry) storage.removeIfExpired(key) { @@ -111,12 +109,11 @@ class DiskStorageSpec: QuickSpec { } } - self.waitForExpectations(withTimeout: 2.0, handler:nil) + self.waitForExpectations(timeout: 2.0, handler:nil) } it("don't remove not expired object") { - let expectation = self.expectation( - withDescription: "Don't Remove If Not Expired Expectation") + let expectation = self.expectation(description: "Don't Remove If Not Expired Expectation") storage.add(key, object: object) storage.removeIfExpired(key) { @@ -126,34 +123,32 @@ class DiskStorageSpec: QuickSpec { } } - self.waitForExpectations(withTimeout: 2.0, handler:nil) + self.waitForExpectations(timeout: 2.0, handler:nil) } } describe("#clear") { it("clears cache directory") { - let expectation = self.expectation(withDescription: "Clear Expectation") + let expectation = self.expectation(description: "Clear Expectation") storage.add(key, object: object) storage.clear() { - let fileExist = fileManager.fileExistsAtPath(storage.path) + let fileExist = fileManager.fileExists(atPath: storage.path) expect(fileExist).to(beFalse()) expectation.fulfill() } - self.waitForExpectations(withTimeout: 2.0, handler:nil) + self.waitForExpectations(timeout: 2.0, handler:nil) } } describe("clearExpired") { it("removes expired objects") { - let expectation1 = self.expectation( - withDescription: "Clear If Expired Expectation") - let expectation2 = self.expectation( - withDescription: "Don't Clear If Not Expired Expectation") + let expectation1 = self.expectation(description: "Clear If Expired Expectation") + let expectation2 = self.expectation(description: "Don't Clear If Not Expired Expectation") - let expiry1: Expiry = .Date(NSDate().dateByAddingTimeInterval(-100000)) - let expiry2: Expiry = .Date(NSDate().dateByAddingTimeInterval(100000)) + let expiry1: Expiry = .date(Date().addingTimeInterval(-100000)) + let expiry2: Expiry = .date(Date().addingTimeInterval(100000)) let key1 = "item1" let key2 = "item2" @@ -173,7 +168,7 @@ class DiskStorageSpec: QuickSpec { } } - self.waitForExpectations(withTimeout: 5.0, handler:nil) + self.waitForExpectations(timeout: 5.0, handler:nil) } } @@ -181,11 +176,9 @@ class DiskStorageSpec: QuickSpec { it("returns a correct file name") { if let digest = key.data(using: String.Encoding.utf8)?.md5() { var string = "" - var byte: UInt8 = 0 - - for i in 0 ..< digest.length { - digest.getBytes(&byte, range: NSMakeRange(i, 1)) - string += String(format: "%02x", byte) + + for byte in digest { + string += String(format:"%02x", byte) } expect(storage.fileName(key)).to(equal(string)) diff --git a/Tests/iOS/Specs/Storage/MemoryStorageSpec.swift b/Tests/iOS/Specs/Storage/MemoryStorageSpec.swift index 2bb31d43..13d32f69 100644 --- a/Tests/iOS/Specs/Storage/MemoryStorageSpec.swift +++ b/Tests/iOS/Specs/Storage/MemoryStorageSpec.swift @@ -21,7 +21,7 @@ class MemoryStorageSpec: QuickSpec { describe("#path") { it("returns the correct path") { - let path = "\(MemoryStorage.prefix).\(name.capitalizedString)" + let path = "\(MemoryStorage.prefix).\(name.capitalized)" expect(storage.path).to(equal(path)) } @@ -35,8 +35,7 @@ class MemoryStorageSpec: QuickSpec { describe("#add") { it("saves an object") { - let expectation = self.expectation( - withDescription: "Save Object Expectation") + let expectation = self.expectation(description: "Save Object Expectation") storage.add(key, object: object) { storage.object(key) { (receivedObject: User?) in @@ -45,14 +44,13 @@ class MemoryStorageSpec: QuickSpec { } } - self.waitForExpectations(withTimeout: 2.0, handler:nil) + self.waitForExpectations(timeout: 2.0, handler:nil) } } describe("#object") { it("resolves cached object") { - let expectation = self.expectation( - withDescription: "Object Expectation") + let expectation = self.expectation(description: "Object Expectation") storage.add(key, object: object) { storage.object(key) { (receivedObject: User?) in @@ -62,14 +60,13 @@ class MemoryStorageSpec: QuickSpec { } } - self.waitForExpectations(withTimeout: 2.0, handler:nil) + self.waitForExpectations(timeout: 2.0, handler:nil) } } describe("#remove") { it("removes cached object") { - let expectation = self.expectation( - withDescription: "Remove Expectation") + let expectation = self.expectation(description: "Remove Expectation") storage.add(key, object: object) storage.remove(key) { @@ -79,15 +76,14 @@ class MemoryStorageSpec: QuickSpec { } } - self.waitForExpectations(withTimeout: 2.0, handler:nil) + self.waitForExpectations(timeout: 2.0, handler:nil) } } describe("removeIfExpired") { it("removes expired object") { - let expectation = self.expectation( - withDescription: "Remove If Expired Expectation") - let expiry: Expiry = .Date(NSDate().dateByAddingTimeInterval(-100000)) + let expectation = self.expectation(description: "Remove If Expired Expectation") + let expiry: Expiry = .date(Date().addingTimeInterval(-100000)) storage.add(key, object: object, expiry: expiry) storage.removeIfExpired(key) { @@ -97,12 +93,11 @@ class MemoryStorageSpec: QuickSpec { } } - self.waitForExpectations(withTimeout: 4.0, handler:nil) + self.waitForExpectations(timeout: 4.0, handler:nil) } it("don't remove not expired object") { - let expectation = self.expectation( - withDescription: "Don't Remove If Not Expired Expectation") + let expectation = self.expectation(description: "Don't Remove If Not Expired Expectation") storage.add(key, object: object) storage.removeIfExpired(key) { @@ -112,14 +107,13 @@ class MemoryStorageSpec: QuickSpec { } } - self.waitForExpectations(withTimeout: 4.0, handler:nil) + self.waitForExpectations(timeout: 4.0, handler:nil) } } describe("#clear") { it("clears cache directory") { - let expectation = self.expectation( - withDescription: "Clear Expectation") + let expectation = self.expectation(description: "Clear Expectation") storage.add(key, object: object) storage.clear() { @@ -129,19 +123,17 @@ class MemoryStorageSpec: QuickSpec { } } - self.waitForExpectations(withTimeout: 2.0, handler:nil) + self.waitForExpectations(timeout: 2.0, handler:nil) } } describe("clearExpired") { it("removes expired objects") { - let expectation1 = self.expectation( - withDescription: "Clear Expired Expectation 1") - let expectation2 = self.expectation( - withDescription: "Clear Expired Expectation 2") + let expectation1 = self.expectation(description: "Clear Expired Expectation 1") + let expectation2 = self.expectation(description: "Clear Expired Expectation 2") - let expiry1: Expiry = .Date(NSDate().dateByAddingTimeInterval(-100000)) - let expiry2: Expiry = .Date(NSDate().dateByAddingTimeInterval(100000)) + let expiry1: Expiry = .date(Date().addingTimeInterval(-100000)) + let expiry2: Expiry = .date(Date().addingTimeInterval(100000)) let key1 = "item1" let key2 = "item2" @@ -161,7 +153,7 @@ class MemoryStorageSpec: QuickSpec { } } - self.waitForExpectations(withTimeout: 5.0, handler:nil) + self.waitForExpectations(timeout: 5.0, handler:nil) } } } diff --git a/Tests/iOS/Specs/Storage/StorageFactorySpec.swift b/Tests/iOS/Specs/Storage/StorageFactorySpec.swift index 79cc2687..62e3bbee 100644 --- a/Tests/iOS/Specs/Storage/StorageFactorySpec.swift +++ b/Tests/iOS/Specs/Storage/StorageFactorySpec.swift @@ -9,15 +9,15 @@ class StorageFactorySpec: QuickSpec { describe(".register") { it("adds an item to the list of registered storages") { - StorageFactory.register(.Memory, storage: MemoryStorage.self) - let resolvedStorage = StorageFactory.resolve("Test", kind: .Memory) + StorageFactory.register(.memory, storage: MemoryStorage.self) + let resolvedStorage = StorageFactory.resolve("Test", kind: .memory) expect(resolvedStorage is MemoryStorage).to(beTrue()) } it("overrides an item in the list of registered storages") { - StorageFactory.register(.Disk, storage: MemoryStorage.self) - let resolvedStorage = StorageFactory.resolve("Test", kind: .Disk) + StorageFactory.register(.disk, storage: MemoryStorage.self) + let resolvedStorage = StorageFactory.resolve("Test", kind: .disk) expect(resolvedStorage is MemoryStorage).to(beTrue()) } @@ -25,7 +25,7 @@ class StorageFactorySpec: QuickSpec { describe(".resolve") { it("returns previously registerd storage") { - let kind: StorageKind = .Custom("Cloud") + let kind: StorageKind = .custom("Cloud") StorageFactory.register(kind, storage: DiskStorage.self) let resolvedStorage = StorageFactory.resolve("Test", kind: kind) @@ -34,8 +34,8 @@ class StorageFactorySpec: QuickSpec { it("returns default registered storages") { StorageFactory.reset() - let memoryStorage = StorageFactory.resolve("Test", kind: .Memory) - let diskStorage = StorageFactory.resolve("Test", kind: .Disk, maxSize: 0) + let memoryStorage = StorageFactory.resolve("Test", kind: .memory) + let diskStorage = StorageFactory.resolve("Test", kind: .disk, maxSize: 0) expect(memoryStorage is MemoryStorage).to(beTrue()) expect(diskStorage is DiskStorage).to(beTrue()) @@ -43,22 +43,22 @@ class StorageFactorySpec: QuickSpec { it("returns memory storage for unresolved kind") { StorageFactory.reset() - let resolvedStorage = StorageFactory.resolve("Test", kind: .Custom("Weirdo")) + let resolvedStorage = StorageFactory.resolve("Test", kind: .custom("Weirdo")) expect(resolvedStorage is MemoryStorage).to(beTrue()) } it("returns a storage with specified maxSize") { - let resolvedStorage = StorageFactory.resolve("Test", kind: .Memory, maxSize: 1000) + let resolvedStorage = StorageFactory.resolve("Test", kind: .memory, maxSize: 1000) expect(resolvedStorage.maxSize).to(equal(1000)) } } describe(".reset") { it("resets to defaults") { - StorageFactory.register(.Disk, storage: MemoryStorage.self) + StorageFactory.register(.disk, storage: MemoryStorage.self) StorageFactory.reset() - let resolvedStorage = StorageFactory.resolve("Test", kind: .Disk) + let resolvedStorage = StorageFactory.resolve("Test", kind: .disk) expect(resolvedStorage is DiskStorage).to(beTrue()) } From d91959958bcbb3853e0ed2a92e5c188b7481f920 Mon Sep 17 00:00:00 2001 From: Vadym Markov Date: Tue, 27 Sep 2016 13:31:50 +0200 Subject: [PATCH 4/7] Fix Mac tests --- Cache.xcodeproj/project.pbxproj | 79 ++----------------- Source/Mac/Extensions/NSImage+Cache.swift | 23 +++--- Source/Mac/HybridCache.swift | 8 +- Source/Shared/Cache.swift | 2 +- Tests/Mac/Helpers/NSImage+CacheTests.swift | 15 ++-- Tests/Mac/Helpers/SpecHelper+OSX.swift | 4 +- .../Specs/Extensions/NSImage+CacheSpec.swift | 13 ++- 7 files changed, 37 insertions(+), 107 deletions(-) diff --git a/Cache.xcodeproj/project.pbxproj b/Cache.xcodeproj/project.pbxproj index edea8274..f6a5c5e4 100644 --- a/Cache.xcodeproj/project.pbxproj +++ b/Cache.xcodeproj/project.pbxproj @@ -7,8 +7,6 @@ objects = { /* Begin PBXBuildFile section */ - 9ABAE0371CCF8FF7009477CF /* CryptoSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9ABAE0361CCF8FF7009477CF /* CryptoSwift.framework */; }; - 9AFE68071CCF994A00B7C6AC /* CryptoSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9AFE68051CCF986C00B7C6AC /* CryptoSwift.framework */; }; D5291C291C28220B00B702C9 /* UIImage+Cache.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5291C0D1C28220B00B702C9 /* UIImage+Cache.swift */; }; D5291C2D1C28220B00B702C9 /* Config.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5291C151C28220B00B702C9 /* Config.swift */; }; D5291C2E1C28220B00B702C9 /* Cachable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5291C171C28220B00B702C9 /* Cachable.swift */; }; @@ -44,8 +42,6 @@ D5291D421C28389B00B702C9 /* DiskStorageSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5291CF11C28374800B702C9 /* DiskStorageSpec.swift */; }; D5291D431C28389B00B702C9 /* MemoryStorageSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5291CF21C28374800B702C9 /* MemoryStorageSpec.swift */; }; D5291D441C28389B00B702C9 /* StorageFactorySpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5291CF31C28374800B702C9 /* StorageFactorySpec.swift */; }; - D5291D571C283A4200B702C9 /* Quick.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D5DC5A6C1C205C2A003BD79B /* Quick.framework */; }; - D5291D581C283A4200B702C9 /* Nimble.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D5DC5A6D1C205C2A003BD79B /* Nimble.framework */; }; D5291D6A1C283B5400B702C9 /* Cache.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D5291D601C283B5300B702C9 /* Cache.framework */; }; D5291D7D1C283BF200B702C9 /* NSImage+Cache.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5291D791C283BE300B702C9 /* NSImage+Cache.swift */; }; D5291D7E1C283BF200B702C9 /* HybridCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5291D7A1C283BE300B702C9 /* HybridCache.swift */; }; @@ -68,7 +64,6 @@ D5291D961C283CFB00B702C9 /* StorageFactory.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5291C271C28220B00B702C9 /* StorageFactory.swift */; }; D5291D9A1C283DB300B702C9 /* UIImage+CacheSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5291D991C283DB300B702C9 /* UIImage+CacheSpec.swift */; }; D5291D9C1C283DD900B702C9 /* NSImage+CacheSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5291D9B1C283DD900B702C9 /* NSImage+CacheSpec.swift */; }; - D5291D9E1C283EC000B702C9 /* Nimble.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D5291CDA1C2835D000B702C9 /* Nimble.framework */; }; D5291DA11C28405900B702C9 /* UIImage+CacheTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5291DA01C28405900B702C9 /* UIImage+CacheTests.swift */; }; D5291DA31C2841D200B702C9 /* NSImage+CacheTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5291DA21C2841D200B702C9 /* NSImage+CacheTests.swift */; }; D5ACACC91CD01F3400567809 /* SyncCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5ACACC81CD01F3400567809 /* SyncCache.swift */; }; @@ -79,9 +74,6 @@ D5ACACD51CD0256700567809 /* SyncHybridCacheSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5ACACD21CD0254300567809 /* SyncHybridCacheSpec.swift */; }; D5ACACDE1CD0272600567809 /* Cache.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5ACACDD1CD0272600567809 /* Cache.swift */; }; D5ACACDF1CD0272600567809 /* Cache.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5ACACDD1CD0272600567809 /* Cache.swift */; }; - D5BAEBF31CD1F4B70003E865 /* Quick.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9AFE68031CCF982800B7C6AC /* Quick.framework */; }; - D5BAEBF51CD1F57D0003E865 /* CryptoSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9ABAE0361CCF8FF7009477CF /* CryptoSwift.framework */; }; - D5BAEBF61CD1F6250003E865 /* CryptoSwift.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9AFE68051CCF986C00B7C6AC /* CryptoSwift.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -102,9 +94,6 @@ /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ - 9ABAE0361CCF8FF7009477CF /* CryptoSwift.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CryptoSwift.framework; path = Carthage/Build/iOS/CryptoSwift.framework; sourceTree = ""; }; - 9AFE68031CCF982800B7C6AC /* Quick.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Quick.framework; path = Carthage/Build/Mac/Quick.framework; sourceTree = ""; }; - 9AFE68051CCF986C00B7C6AC /* CryptoSwift.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CryptoSwift.framework; path = Carthage/Build/Mac/CryptoSwift.framework; sourceTree = ""; }; D5291C0D1C28220B00B702C9 /* UIImage+Cache.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+Cache.swift"; sourceTree = ""; }; D5291C151C28220B00B702C9 /* Config.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Config.swift; sourceTree = ""; }; D5291C171C28220B00B702C9 /* Cachable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Cachable.swift; sourceTree = ""; }; @@ -123,7 +112,6 @@ D5291C271C28220B00B702C9 /* StorageFactory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StorageFactory.swift; sourceTree = ""; }; D5291C6A1C2827FB00B702C9 /* BasicHybridCache.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BasicHybridCache.swift; sourceTree = ""; }; D5291C721C28296B00B702C9 /* HybridCache.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HybridCache.swift; sourceTree = ""; }; - D5291CDA1C2835D000B702C9 /* Nimble.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Nimble.framework; path = Carthage/Build/Mac/Nimble.framework; sourceTree = ""; }; D5291CDF1C28374800B702C9 /* SpecHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SpecHelper.swift; sourceTree = ""; }; D5291CE01C28374800B702C9 /* User.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = User.swift; sourceTree = ""; }; D5291CE21C28374800B702C9 /* CacheSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CacheSpec.swift; sourceTree = ""; }; @@ -161,8 +149,6 @@ D5ACACDD1CD0272600567809 /* Cache.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Cache.swift; sourceTree = ""; }; D5DC59E01C20593E003BD79B /* Cache.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Cache.framework; sourceTree = BUILT_PRODUCTS_DIR; }; D5DC5A181C205AC9003BD79B /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - D5DC5A6C1C205C2A003BD79B /* Quick.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Quick.framework; path = Carthage/Build/iOS/Quick.framework; sourceTree = ""; }; - D5DC5A6D1C205C2A003BD79B /* Nimble.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Nimble.framework; path = Carthage/Build/iOS/Nimble.framework; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -171,9 +157,6 @@ buildActionMask = 2147483647; files = ( D5291D1D1C2837DB00B702C9 /* Cache.framework in Frameworks */, - D5BAEBF51CD1F57D0003E865 /* CryptoSwift.framework in Frameworks */, - D5291D571C283A4200B702C9 /* Quick.framework in Frameworks */, - D5291D581C283A4200B702C9 /* Nimble.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -181,7 +164,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 9AFE68071CCF994A00B7C6AC /* CryptoSwift.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -190,9 +172,6 @@ buildActionMask = 2147483647; files = ( D5291D6A1C283B5400B702C9 /* Cache.framework in Frameworks */, - D5BAEBF61CD1F6250003E865 /* CryptoSwift.framework in Frameworks */, - D5BAEBF31CD1F4B70003E865 /* Quick.framework in Frameworks */, - D5291D9E1C283EC000B702C9 /* Nimble.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -200,7 +179,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 9ABAE0371CCF8FF7009477CF /* CryptoSwift.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -420,35 +398,6 @@ path = Extensions; sourceTree = ""; }; - D5291DA41C28452300B702C9 /* Frameworks */ = { - isa = PBXGroup; - children = ( - D5291DA61C28454800B702C9 /* iOS */, - D5291DA51C28454000B702C9 /* Mac */, - ); - name = Frameworks; - sourceTree = ""; - }; - D5291DA51C28454000B702C9 /* Mac */ = { - isa = PBXGroup; - children = ( - 9AFE68051CCF986C00B7C6AC /* CryptoSwift.framework */, - 9AFE68031CCF982800B7C6AC /* Quick.framework */, - D5291CDA1C2835D000B702C9 /* Nimble.framework */, - ); - name = Mac; - sourceTree = ""; - }; - D5291DA61C28454800B702C9 /* iOS */ = { - isa = PBXGroup; - children = ( - 9ABAE0361CCF8FF7009477CF /* CryptoSwift.framework */, - D5DC5A6C1C205C2A003BD79B /* Quick.framework */, - D5DC5A6D1C205C2A003BD79B /* Nimble.framework */, - ); - name = iOS; - sourceTree = ""; - }; D5643E341C43F2CC00582E17 /* Playgrounds */ = { isa = PBXGroup; children = ( @@ -462,7 +411,6 @@ isa = PBXGroup; children = ( D5643E341C43F2CC00582E17 /* Playgrounds */, - D5291DA41C28452300B702C9 /* Frameworks */, D5291C081C28220B00B702C9 /* Source */, D5DC5A161C205AC9003BD79B /* SupportFiles */, D5DC59FA1C205AC9003BD79B /* Tests */, @@ -545,8 +493,7 @@ D5291D5C1C283B5300B702C9 /* Frameworks */, D5291D5D1C283B5300B702C9 /* Headers */, D5291D5E1C283B5300B702C9 /* Resources */, - D5BAEBF41CD1F4D30003E865 /* ShellScript */, - BD58C3AE1CF2EA04003F7141 /* ShellScript */, + BD58C3AE1CF2EA04003F7141 /* SwiftLint */, ); buildRules = ( ); @@ -584,7 +531,7 @@ D5DC59DC1C20593E003BD79B /* Frameworks */, D5DC59DD1C20593E003BD79B /* Headers */, D5DC59DE1C20593E003BD79B /* Resources */, - BD58C3AD1CF2E9FD003F7141 /* ShellScript */, + BD58C3AD1CF2E9FD003F7141 /* SwiftLint */, ); buildRules = ( ); @@ -673,26 +620,28 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - BD58C3AD1CF2E9FD003F7141 /* ShellScript */ = { + BD58C3AD1CF2E9FD003F7141 /* SwiftLint */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); + name = SwiftLint; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "if which swiftlint >/dev/null; then\n swiftlint\nelse\n echo \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi"; }; - BD58C3AE1CF2EA04003F7141 /* ShellScript */ = { + BD58C3AE1CF2EA04003F7141 /* SwiftLint */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); + name = SwiftLint; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; @@ -731,20 +680,6 @@ shellPath = /bin/sh; shellScript = "/usr/local/bin/carthage copy-frameworks"; }; - D5BAEBF41CD1F4D30003E865 /* ShellScript */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - "$(SRCROOT)/Carthage/Build/Mac/CryptoSwift.framework", - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "/usr/local/bin/carthage copy-frameworks"; - }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -1080,7 +1015,6 @@ FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Carthage/Build/iOS", - "$(PROJECT_DIR)/Carthage/Build/Mac", ); INFOPLIST_FILE = "$(SRCROOT)/SupportFiles/iOS/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; @@ -1104,7 +1038,6 @@ FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)/Carthage/Build/iOS", - "$(PROJECT_DIR)/Carthage/Build/Mac", ); INFOPLIST_FILE = "$(SRCROOT)/SupportFiles/iOS/Info.plist"; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; diff --git a/Source/Mac/Extensions/NSImage+Cache.swift b/Source/Mac/Extensions/NSImage+Cache.swift index ea8a2c4b..838c8ff6 100644 --- a/Source/Mac/Extensions/NSImage+Cache.swift +++ b/Source/Mac/Extensions/NSImage+Cache.swift @@ -16,7 +16,7 @@ extension NSImage: Cachable { - Parameter data: Data to decode from - Returns: Optional CacheType */ - public static func decode(data: NSData) -> CacheType? { + public static func decode(_ data: Data) -> CacheType? { let image = NSImage(data: data) return image } @@ -25,14 +25,11 @@ extension NSImage: Cachable { Encodes UIImage to NSData - Returns: Optional NSData */ - public func encode() -> NSData? { - guard let data = TIFFRepresentation else { return nil } + public func encode() -> Data? { + guard let data = tiffRepresentation else { return nil } - let imageFileType: NSBitmapImageFileType = hasAlpha - ? .NSPNGFileType - : .NSJPEGFileType - - return NSBitmapImageRep(data: data)?.representationUsingType(imageFileType, properties: [:]) + let imageFileType: NSBitmapImageFileType = hasAlpha ? .PNG : .JPEG + return NSBitmapImageRep(data: data)?.representation(using: imageFileType, properties: [:]) } } @@ -48,12 +45,16 @@ extension NSImage { */ var hasAlpha: Bool { var imageRect: CGRect = CGRect(x: 0, y: 0, width: size.width, height: size.height) - let imageRef = CGImageForProposedRect(&imageRect, context: nil, hints: nil) + + guard let imageRef = cgImage(forProposedRect: &imageRect, context: nil, hints: nil) else { + return false + } + let result: Bool - let alpha = CGImageGetAlphaInfo(imageRef) + let alpha = imageRef.alphaInfo switch alpha { - case .None, .NoneSkipFirst, .NoneSkipLast: + case .none, .noneSkipFirst, .noneSkipLast: result = false default: result = true diff --git a/Source/Mac/HybridCache.swift b/Source/Mac/HybridCache.swift index 7a4ed366..d8ab0e57 100644 --- a/Source/Mac/HybridCache.swift +++ b/Source/Mac/HybridCache.swift @@ -18,19 +18,19 @@ public class HybridCache: BasicHybridCache { public override init(name: String, config: Config = Config.defaultConfig) { super.init(name: name, config: config) - let notificationCenter = NSNotificationCenter.defaultCenter() + let notificationCenter = NotificationCenter.default notificationCenter.addObserver(self, selector: #selector(HybridCache.applicationWillTerminate), - name: NSApplicationWillTerminateNotification, object: nil) + name: NSNotification.Name.NSApplicationWillTerminate, object: nil) notificationCenter.addObserver(self, selector: #selector(HybridCache.applicationDidResignActive), - name: NSApplicationDidResignActiveNotification, object: nil) + name: NSNotification.Name.NSApplicationDidResignActive, object: nil) } /** Removes notification center observer. */ deinit { - NSNotificationCenter.defaultCenter().removeObserver(self) + NotificationCenter.default.removeObserver(self) } // MARK: - Notifications diff --git a/Source/Shared/Cache.swift b/Source/Shared/Cache.swift index cc5b007c..0fbe9e7d 100644 --- a/Source/Shared/Cache.swift +++ b/Source/Shared/Cache.swift @@ -5,7 +5,7 @@ import Foundation Cachable protocol. It's two layered cache (with front and back storages). Subscribes to system notifications to clear expired cached objects. */ -open class Cache: HybridCache { +public class Cache: HybridCache { // MARK: - Initialization diff --git a/Tests/Mac/Helpers/NSImage+CacheTests.swift b/Tests/Mac/Helpers/NSImage+CacheTests.swift index 0e612be0..a5445961 100644 --- a/Tests/Mac/Helpers/NSImage+CacheTests.swift +++ b/Tests/Mac/Helpers/NSImage+CacheTests.swift @@ -4,17 +4,16 @@ import Cocoa extension NSImage { func isEqualToImage(image: NSImage) -> Bool { - return data.isEqualToData(image.data) + return data == image.data } - var data: NSData { - let representation = TIFFRepresentation! + var data: Data { + let representation = tiffRepresentation! - let imageFileType: NSBitmapImageFileType = hasAlpha - ? .NSPNGFileType - : .NSJPEGFileType + let imageFileType: NSBitmapImageFileType = hasAlpha ? .PNG : .JPEG - return (NSBitmapImageRep(data: representation)?.representationUsingType( - imageFileType, properties: [:]))! + return (NSBitmapImageRep(data: representation)?.representation( + using: imageFileType, + properties: [:]))! } } diff --git a/Tests/Mac/Helpers/SpecHelper+OSX.swift b/Tests/Mac/Helpers/SpecHelper+OSX.swift index 49519791..179f2176 100644 --- a/Tests/Mac/Helpers/SpecHelper+OSX.swift +++ b/Tests/Mac/Helpers/SpecHelper+OSX.swift @@ -2,10 +2,10 @@ import Cocoa struct SpecHelper { - static func image(color: NSColor = NSColor.redColor(), size: NSSize = CGSize(width: 1, height: 1)) -> NSImage { + static func image(color: NSColor = NSColor.red, size: NSSize = CGSize(width: 1, height: 1)) -> NSImage { let image = NSImage(size: size) image.lockFocus() - color.drawSwatchInRect(NSMakeRect(0, 0, size.width, size.height)) + color.drawSwatch(in: NSMakeRect(0, 0, size.width, size.height)) image.unlockFocus() return image } diff --git a/Tests/Mac/Specs/Extensions/NSImage+CacheSpec.swift b/Tests/Mac/Specs/Extensions/NSImage+CacheSpec.swift index e2ee84ff..db328247 100644 --- a/Tests/Mac/Specs/Extensions/NSImage+CacheSpec.swift +++ b/Tests/Mac/Specs/Extensions/NSImage+CacheSpec.swift @@ -14,21 +14,18 @@ class NSImageCacheSpec: QuickSpec { let data = image.encode()! let result = NSImage.decode(data)! - expect(result.isEqualToImage(image)).to(beTrue()) + expect(result.isEqualToImage(image: image)).to(beTrue()) } } describe("#encode") { it("encodes to NSData") { let image = SpecHelper.image() - let representation = image.TIFFRepresentation! + let representation = image.tiffRepresentation! - let imageFileType: NSBitmapImageFileType = image.hasAlpha - ? .NSPNGFileType - : .NSJPEGFileType - - let data = NSBitmapImageRep(data: representation)!.representationUsingType( - imageFileType, properties: [:]) + let imageFileType: NSBitmapImageFileType = image.hasAlpha ? .PNG : .JPEG + let data = NSBitmapImageRep(data: representation)!.representation( + using: imageFileType, properties: [:]) let result = image.encode()! From f4f1398fe02c762630a802b5e5ae9c334beafed9 Mon Sep 17 00:00:00 2001 From: Vadym Markov Date: Tue, 27 Sep 2016 13:41:14 +0200 Subject: [PATCH 5/7] Refactor code --- Cache.xcodeproj/project.pbxproj | 2 +- Source/Shared/BasicHybridCache.swift | 14 ++--- Source/Shared/Cache.swift | 6 +- Source/Shared/DataStructures/Capsule.swift | 2 +- Source/Shared/Storage/DiskStorage.swift | 64 +++++++++++----------- Source/Shared/Storage/MemoryStorage.swift | 26 ++++----- Source/Shared/Storage/StorageFactory.swift | 2 +- Source/iOS/HybridCache.swift | 2 +- 8 files changed, 59 insertions(+), 59 deletions(-) diff --git a/Cache.xcodeproj/project.pbxproj b/Cache.xcodeproj/project.pbxproj index f6a5c5e4..201fcd5e 100644 --- a/Cache.xcodeproj/project.pbxproj +++ b/Cache.xcodeproj/project.pbxproj @@ -349,8 +349,8 @@ D5291D771C283BE300B702C9 /* Mac */ = { isa = PBXGroup; children = ( - D5291D781C283BE300B702C9 /* Extensions */, D5291D7A1C283BE300B702C9 /* HybridCache.swift */, + D5291D781C283BE300B702C9 /* Extensions */, ); path = Mac; sourceTree = ""; diff --git a/Source/Shared/BasicHybridCache.swift b/Source/Shared/BasicHybridCache.swift index 57677e4f..ee24ce4b 100644 --- a/Source/Shared/BasicHybridCache.swift +++ b/Source/Shared/BasicHybridCache.swift @@ -4,10 +4,10 @@ import Foundation BasicHybridCache supports storing all kinds of objects, as long as they conform to Cachable protocol. It's two layered cache (with front and back storages) */ -open class BasicHybridCache: NSObject { +public class BasicHybridCache: NSObject { /// A name of the cache - open let name: String + public let name: String /// Cache configuration let config: Config @@ -16,7 +16,7 @@ open class BasicHybridCache: NSObject { // BAck cache (used for content that outlives the application life-cycle) var backStorage: StorageAware - open var path: String { + public var path: String { return backStorage.path } @@ -48,7 +48,7 @@ open class BasicHybridCache: NSObject { - Parameter expiry: Expiration date for the cached object - Parameter completion: Completion closure to be called when the task is done */ - open func add(_ key: String, object: T, expiry: Expiry? = nil, completion: (() -> Void)? = nil) { + public func add(_ key: String, object: T, expiry: Expiry? = nil, completion: (() -> Void)? = nil) { let expiry = expiry ?? config.expiry frontStorage.add(key, object: object, expiry: expiry) { [weak self] in @@ -69,7 +69,7 @@ open class BasicHybridCache: NSObject { - Parameter key: Unique key to identify the object in the cache - Parameter completion: Completion closure returns object or nil */ - open func object(_ key: String, completion: @escaping (_ object: T?) -> Void) { + public func object(_ key: String, completion: @escaping (_ object: T?) -> Void) { frontStorage.object(key) { [weak self] (object: T?) in if let object = object { completion(object) @@ -93,7 +93,7 @@ open class BasicHybridCache: NSObject { - Parameter key: Unique key to identify the object in the cache - Parameter completion: Completion closure to be called when the task is done */ - open func remove(_ key: String, completion: (() -> Void)? = nil) { + public func remove(_ key: String, completion: (() -> Void)? = nil) { frontStorage.remove(key) { [weak self] in guard let weakSelf = self else { completion?() @@ -111,7 +111,7 @@ open class BasicHybridCache: NSObject { - Parameter completion: Completion closure to be called when the task is done */ - open func clear(_ completion: (() -> Void)? = nil) { + public func clear(_ completion: (() -> Void)? = nil) { frontStorage.clear() { [weak self] in guard let weakSelf = self else { completion?() diff --git a/Source/Shared/Cache.swift b/Source/Shared/Cache.swift index 0fbe9e7d..d3526834 100644 --- a/Source/Shared/Cache.swift +++ b/Source/Shared/Cache.swift @@ -5,7 +5,7 @@ import Foundation Cachable protocol. It's two layered cache (with front and back storages). Subscribes to system notifications to clear expired cached objects. */ -public class Cache: HybridCache { +public final class Cache: HybridCache { // MARK: - Initialization @@ -29,7 +29,7 @@ public class Cache: HybridCache { - Parameter expiry: Expiration date for the cached object - Parameter completion: Completion closure to be called when the task is done */ - open override func add(_ key: String, object: T, expiry: Expiry? = nil, completion: (() -> Void)? = nil) { + public override func add(_ key: String, object: T, expiry: Expiry? = nil, completion: (() -> Void)? = nil) { super.add(key, object: object, expiry: expiry, completion: completion) } @@ -39,7 +39,7 @@ public class Cache: HybridCache { - Parameter key: Unique key to identify the object in the cache - Parameter completion: Completion closure returns object or nil */ - open override func object(_ key: String, completion: @escaping (_ object: T?) -> Void) { + public override func object(_ key: String, completion: @escaping (_ object: T?) -> Void) { super.object(key, completion: completion) } } diff --git a/Source/Shared/DataStructures/Capsule.swift b/Source/Shared/DataStructures/Capsule.swift index dcb7e394..0e011564 100644 --- a/Source/Shared/DataStructures/Capsule.swift +++ b/Source/Shared/DataStructures/Capsule.swift @@ -4,7 +4,7 @@ import Foundation Helper class to hold cached instance and expiry date. Used in memory storage to work with NSCache. */ -class Capsule: NSObject { +final class Capsule: NSObject { /// Object to be cached let object: Any diff --git a/Source/Shared/Storage/DiskStorage.swift b/Source/Shared/Storage/DiskStorage.swift index 73e79a27..d3e8c32b 100644 --- a/Source/Shared/Storage/DiskStorage.swift +++ b/Source/Shared/Storage/DiskStorage.swift @@ -1,42 +1,22 @@ import Foundation import CryptoSwift -fileprivate func < (lhs: T?, rhs: T?) -> Bool { - switch (lhs, rhs) { - case let (l?, r?): - return l < r - case (nil, _?): - return true - default: - return false - } -} - -fileprivate func > (lhs: T?, rhs: T?) -> Bool { - switch (lhs, rhs) { - case let (l?, r?): - return l > r - default: - return rhs < lhs - } -} - /** File-based cache storage */ -open class DiskStorage: StorageAware { +public final class DiskStorage: StorageAware { /// Domain prefix - open static let prefix = "no.hyper.Cache.Disk" + public static let prefix = "no.hyper.Cache.Disk" /// Storage root path - open let path: String + public let path: String /// Maximum size of the cache storage - open var maxSize: UInt + public var maxSize: UInt /// Queue for write operations - open fileprivate(set) var writeQueue: DispatchQueue + public fileprivate(set) var writeQueue: DispatchQueue /// Queue for read operations - open fileprivate(set) var readQueue: DispatchQueue + public fileprivate(set) var readQueue: DispatchQueue /// File manager to read/write to the disk fileprivate lazy var fileManager: FileManager = { @@ -75,7 +55,7 @@ open class DiskStorage: StorageAware { - Parameter expiry: Expiration date for the cached object - Parameter completion: Completion closure to be called when the task is done */ - open func add(_ key: String, object: T, expiry: Expiry = .never, completion: (() -> Void)? = nil) { + public func add(_ key: String, object: T, expiry: Expiry = .never, completion: (() -> Void)? = nil) { writeQueue.async { [weak self] in guard let weakSelf = self else { completion?() @@ -108,7 +88,7 @@ open class DiskStorage: StorageAware { - Parameter key: Unique key to identify the object in the cache - Parameter completion: Completion closure returns object or nil */ - open func object(_ key: String, completion: @escaping (_ object: T?) -> Void) { + public func object(_ key: String, completion: @escaping (_ object: T?) -> Void) { readQueue.async { [weak self] in guard let weakSelf = self else { completion(nil) @@ -132,7 +112,7 @@ open class DiskStorage: StorageAware { - Parameter key: Unique key to identify the object in the cache - Parameter completion: Completion closure to be called when the task is done */ - open func remove(_ key: String, completion: (() -> Void)? = nil) { + public func remove(_ key: String, completion: (() -> Void)? = nil) { writeQueue.async { [weak self] in guard let weakSelf = self else { completion?() @@ -153,7 +133,7 @@ open class DiskStorage: StorageAware { - Parameter key: Unique key to identify the object in the cache - Parameter completion: Completion closure to be called when the task is done */ - open func removeIfExpired(_ key: String, completion: (() -> Void)?) { + public func removeIfExpired(_ key: String, completion: (() -> Void)?) { let path = filePath(key) writeQueue.async { [weak self] in @@ -179,7 +159,7 @@ open class DiskStorage: StorageAware { - Parameter completion: Completion closure to be called when the task is done */ - open func clear(_ completion: (() -> Void)? = nil) { + public func clear(_ completion: (() -> Void)? = nil) { writeQueue.async { [weak self] in guard let weakSelf = self else { completion?() @@ -201,7 +181,7 @@ open class DiskStorage: StorageAware { - Parameter completion: Completion closure to be called when the task is done */ - open func clearExpired(_ completion: (() -> Void)? = nil) { + public func clearExpired(_ completion: (() -> Void)? = nil) { writeQueue.async { [weak self] in guard let weakSelf = self else { completion?() @@ -318,3 +298,23 @@ open class DiskStorage: StorageAware { return "\(path)/\(fileName(key))" } } + +fileprivate func < (lhs: T?, rhs: T?) -> Bool { + switch (lhs, rhs) { + case let (l?, r?): + return l < r + case (nil, _?): + return true + default: + return false + } +} + +fileprivate func > (lhs: T?, rhs: T?) -> Bool { + switch (lhs, rhs) { + case let (l?, r?): + return l > r + default: + return rhs < lhs + } +} diff --git a/Source/Shared/Storage/MemoryStorage.swift b/Source/Shared/Storage/MemoryStorage.swift index 205883d9..ab5382b8 100644 --- a/Source/Shared/Storage/MemoryStorage.swift +++ b/Source/Shared/Storage/MemoryStorage.swift @@ -3,25 +3,25 @@ import Foundation /** Memory cache storage based on NSCache */ -open class MemoryStorage: StorageAware { +public final class MemoryStorage: StorageAware { /// Domain prefix - open static let prefix = "no.hyper.Cache.Memory" + public static let prefix = "no.hyper.Cache.Memory" /// Storage root path - open var path: String { + public var path: String { return cache.name } /// Maximum size of the cache storage - open var maxSize: UInt + public var maxSize: UInt /// Memory cache instance - open let cache = NSCache() + public let cache = NSCache() /// Queue for write operations - open fileprivate(set) var writeQueue: DispatchQueue + public fileprivate(set) var writeQueue: DispatchQueue /// Queue for read operations - open fileprivate(set) var readQueue: DispatchQueue + public fileprivate(set) var readQueue: DispatchQueue // MARK: - Initialization @@ -51,7 +51,7 @@ open class MemoryStorage: StorageAware { - Parameter expiry: Expiration date for the cached object - Parameter completion: Completion closure to be called when the task is done */ - open func add(_ key: String, object: T, expiry: Expiry = .never, completion: (() -> Void)? = nil) { + public func add(_ key: String, object: T, expiry: Expiry = .never, completion: (() -> Void)? = nil) { writeQueue.async { [weak self] in guard let weakSelf = self else { completion?() @@ -71,7 +71,7 @@ open class MemoryStorage: StorageAware { - Parameter key: Unique key to identify the object in the cache - Parameter completion: Completion closure returns object or nil */ - open func object(_ key: String, completion: @escaping (_ object: T?) -> Void) { + public func object(_ key: String, completion: @escaping (_ object: T?) -> Void) { readQueue.async { [weak self] in guard let weakSelf = self else { completion(nil) @@ -93,7 +93,7 @@ open class MemoryStorage: StorageAware { - Parameter key: Unique key to identify the object in the cache - Parameter completion: Completion closure to be called when the task is done */ - open func remove(_ key: String, completion: (() -> Void)? = nil) { + public func remove(_ key: String, completion: (() -> Void)? = nil) { writeQueue.async { [weak self] in guard let weakSelf = self else { completion?() @@ -111,7 +111,7 @@ open class MemoryStorage: StorageAware { - Parameter key: Unique key to identify the object in the cache - Parameter completion: Completion closure to be called when the task is done */ - open func removeIfExpired(_ key: String, completion: (() -> Void)?) { + public func removeIfExpired(_ key: String, completion: (() -> Void)?) { writeQueue.async { [weak self] in guard let weakSelf = self else { completion?() @@ -131,7 +131,7 @@ open class MemoryStorage: StorageAware { - Parameter completion: Completion closure to be called when the task is done */ - open func clear(_ completion: (() -> Void)? = nil) { + public func clear(_ completion: (() -> Void)? = nil) { writeQueue.async { [weak self] in guard let weakSelf = self else { completion?() @@ -148,7 +148,7 @@ open class MemoryStorage: StorageAware { - Parameter completion: Completion closure to be called when the task is done */ - open func clearExpired(_ completion: (() -> Void)? = nil) { + public func clearExpired(_ completion: (() -> Void)? = nil) { clear(completion) } diff --git a/Source/Shared/Storage/StorageFactory.swift b/Source/Shared/Storage/StorageFactory.swift index c9529495..eb86e516 100644 --- a/Source/Shared/Storage/StorageFactory.swift +++ b/Source/Shared/Storage/StorageFactory.swift @@ -1,7 +1,7 @@ /** A place to register and retrieve a cache storage by type. */ -open class StorageFactory { +public final class StorageFactory { /// Default storage type fileprivate static var DefaultStorage: StorageAware.Type = MemoryStorage.self diff --git a/Source/iOS/HybridCache.swift b/Source/iOS/HybridCache.swift index e62c7d8e..82826b9e 100644 --- a/Source/iOS/HybridCache.swift +++ b/Source/iOS/HybridCache.swift @@ -5,7 +5,7 @@ import UIKit Cachable protocol. It's two layered cache (with front and back storages), as well as Cache. Subscribes to system notifications to clear expired cached objects. */ -open class HybridCache: BasicHybridCache { +public class HybridCache: BasicHybridCache { // MARK: - Inititalization From 0246e9e9e8faae93f2c83d15824789577f4720bf Mon Sep 17 00:00:00 2001 From: Christoffer Winterkvist Date: Thu, 6 Oct 2016 07:37:38 +0200 Subject: [PATCH 6/7] Add s.pod_target_xcconfig = { 'SWIFT_VERSION' => '3.0' } --- Cache.podspec | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Cache.podspec b/Cache.podspec index d7582baa..21c987c0 100644 --- a/Cache.podspec +++ b/Cache.podspec @@ -19,4 +19,6 @@ Pod::Spec.new do |s| s.frameworks = 'Foundation' s.dependency 'CryptoSwift' + + s.pod_target_xcconfig = { 'SWIFT_VERSION' => '3.0' } end From 1007304167d9f2efdd97c086c077d477069016b9 Mon Sep 17 00:00:00 2001 From: Christoffer Winterkvist Date: Wed, 12 Oct 2016 20:30:52 +0200 Subject: [PATCH 7/7] Update travis configuration with disabling emails --- .travis.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.travis.yml b/.travis.yml index 41758e6c..1e85bc59 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,3 +11,6 @@ script: - xcodebuild test -project Cache.xcodeproj -scheme "Cache-Mac" -sdk macosx - xcodebuild clean build -project Cache.xcodeproj -scheme "Cache-iOS" -sdk iphonesimulator - xcodebuild test -project Cache.xcodeproj -scheme "Cache-iOS" -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 6,OS=10.0' + +notifications: + email: false