Skip to content

Commit

Permalink
Merge pull request #80 from hyperoslo/refactor/cache-types
Browse files Browse the repository at this point in the history
Fix generic Cache class
  • Loading branch information
vadymmarkov authored May 2, 2017
2 parents 19d0bb6 + c9fa626 commit 26ea6f6
Show file tree
Hide file tree
Showing 12 changed files with 145 additions and 223 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
osx_image: xcode8
osx_image: xcode8.2
language: objective-c

cache:
Expand Down
54 changes: 18 additions & 36 deletions Cache.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions Cartfile.resolved
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
github "krzyzanowskim/CryptoSwift" "0.6.1"
github "Quick/Nimble" "v5.1.0"
github "Quick/Quick" "v0.10.0"
github "krzyzanowskim/CryptoSwift" "0.6.8"
github "Quick/Nimble" "v6.1.0"
github "Quick/Quick" "v1.1.0"
58 changes: 0 additions & 58 deletions Source/Mac/HybridCache.swift

This file was deleted.

File renamed without changes.
92 changes: 85 additions & 7 deletions Source/Shared/BasicHybridCache.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import Foundation
#if os(macOS)
import AppKit
#else
import UIKit
#endif

/**
BasicHybridCache supports storing all kinds of objects, as long as they conform to
Expand Down Expand Up @@ -34,21 +38,44 @@ public class BasicHybridCache: NSObject {

frontStorage = StorageFactory.resolve(name, kind: config.frontKind, maxSize: UInt(config.maxObjects))
backStorage = StorageFactory.resolve(name, kind: config.backKind, maxSize: config.maxSize)

super.init()

let notificationCenter = NotificationCenter.default

#if os(macOS)
notificationCenter.addObserver(self, selector: #selector(clearExpiredDataInBackStorage),
name: NSNotification.Name.NSApplicationWillTerminate, object: nil)
notificationCenter.addObserver(self, selector: #selector(clearExpiredDataInBackStorage),
name: NSNotification.Name.NSApplicationDidResignActive, object: nil)
#else
notificationCenter.addObserver(self, selector: #selector(clearExpiredDataInFrontStorage),
name: .UIApplicationDidReceiveMemoryWarning, object: nil)
notificationCenter.addObserver(self, selector: #selector(clearExpiredDataInBackStorage),
name: .UIApplicationWillTerminate, object: nil)
notificationCenter.addObserver(self, selector: #selector(HybridCache.applicationDidEnterBackground),
name: .UIApplicationDidEnterBackground, object: nil)
#endif
}

/**
Removes notification center observer.
*/
deinit {
NotificationCenter.default.removeObserver(self)
}

// MARK: - Caching

/**
Adds passed object to the front and back cache storages.
- Parameter key: Unique key to identify the object in the cache
- Parameter object: Object that needs to be cached
- Parameter key: Unique key to identify the object in the cache
- Parameter expiry: Expiration date for the cached object
- Parameter completion: Completion closure to be called when the task is done
*/
public func add<T: Cachable>(_ key: String, object: T, expiry: Expiry? = nil, completion: (() -> Void)? = nil) {
func add<T: Cachable>(_ object: T, forKey key: String,
expiry: Expiry? = nil, completion: (() -> Void)? = nil) {
let expiry = expiry ?? config.expiry

frontStorage.add(key, object: object, expiry: expiry) { [weak self] in
Expand All @@ -69,7 +96,7 @@ 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<T: Cachable>(_ key: String, completion: @escaping (_ object: T?) -> Void) {
func object<T: Cachable>(forKey key: String, completion: @escaping (_ object: T?) -> Void) {
frontStorage.object(key) { [weak self] (object: T?) in
if let object = object {
completion(object)
Expand Down Expand Up @@ -126,7 +153,7 @@ public class BasicHybridCache: NSObject {

/**
Clears all expired objects from front and back storages.
- Parameter completion: Completion closure to be called when the task is done
*/
public func clearExpired(_ completion: (() -> Void)? = nil) {
Expand All @@ -135,10 +162,61 @@ public class BasicHybridCache: NSObject {
completion?()
return
}

weakSelf.backStorage.clearExpired() {
completion?()
}
}
}

/**
Clears expired cache items in front cache.
*/
func clearExpiredDataInFrontStorage() {
frontStorage.clearExpired(nil)
}

/**
Clears expired cache items in back cache.
*/
func clearExpiredDataInBackStorage() {
backStorage.clearExpired(nil)
}

#if !os(macOS)

/**
Clears expired cache items when the app enters background.
*/
func applicationDidEnterBackground() {
let application = UIApplication.shared
var backgroundTask: UIBackgroundTaskIdentifier?

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, let backgroundTask = backgroundTask else { return }
var mutableBackgroundTask = backgroundTask

DispatchQueue.main.async {
weakSelf.endBackgroundTask(&mutableBackgroundTask)
}
}
}

/**
Ends given background task.
- Parameter task: A UIBackgroundTaskIdentifier
*/
func endBackgroundTask(_ task: inout UIBackgroundTaskIdentifier) {
UIApplication.shared.endBackgroundTask(task)
task = UIBackgroundTaskInvalid
}

#endif
}
36 changes: 7 additions & 29 deletions Source/Shared/Cache.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +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 final class Cache<T: Cachable>: HybridCache {

// MARK: - Initialization

/**
Creates a new instance of Cache.
- Parameter name: A name of the cache
- Parameter config: Cache configuration
*/
public override init(name: String, config: Config = Config.defaultConfig) {
super.init(name: name, config: config)
}
public final class Cache<T: Cachable>: BasicHybridCache {

// MARK: - Caching

Expand All @@ -29,28 +17,18 @@ public final class Cache<T: Cachable>: HybridCache {
- Parameter expiry: Expiration date for the cached object
- Parameter completion: Completion closure to be called when the task is done
*/
#if swift(>=3.1)
public override func add<T: Cachable>(_ key: String, object: T, expiry: Expiry? = nil, completion: (() -> Void)? = nil) {
super.add(key, object: object, expiry: expiry, completion: completion)
}
#else
public override func add(_ key: String, object: T, expiry: Expiry? = nil, completion: (() -> Void)? = nil) {
super.add(key, object: object, expiry: expiry, completion: completion)
public func add(_ key: String, object: T, expiry: Expiry? = nil, completion: (() -> Void)? = nil) {
super.add(object, forKey: key, expiry: expiry, completion: completion)
}
#endif

/**
Tries to retrieve the object from to the front and back cache storages.
- Parameter key: Unique key to identify the object in the cache
- Parameter completion: Completion closure returns object or nil
*/
#if swift(>=3.1)
public override func object<T: Cachable>(_ key: String, completion: @escaping (_ object: T?) -> Void) {
super.object(key, completion: completion)
}
#else
public override func object(_ key: String, completion: @escaping (_ object: T?) -> Void) {
super.object(key, completion: completion)

public func object(_ key: String, completion: @escaping (_ object: T?) -> Void) {
super.object(forKey: key, completion: completion)
}
#endif
}
29 changes: 29 additions & 0 deletions Source/Shared/HybridCache.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/**
HybridCache supports storing all kinds of objects, as long as they conform to
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 {

/**
Adds passed object to the front and back cache storages.
- Parameter key: Unique key to identify the object in the cache
- Parameter object: Object that needs to be cached
- Parameter expiry: Expiration date for the cached object
- Parameter completion: Completion closure to be called when the task is done
*/
public func add<T: Cachable>(_ key: String, object: T, expiry: Expiry? = nil, completion: (() -> Void)? = nil) {
super.add(object, forKey: key, expiry: expiry, completion: completion)
}

/**
Tries to retrieve the object from to the front and back cache storages.
- Parameter key: Unique key to identify the object in the cache
- Parameter completion: Completion closure returns object or nil
*/
public func object<T: Cachable>(_ key: String, completion: @escaping (_ object: T?) -> Void) {
super.object(forKey: key, completion: completion)
}
}
4 changes: 2 additions & 2 deletions Source/Shared/Library/SyncHybridCache.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ public struct SyncHybridCache {
public func add<T: Cachable>(_ key: String, object: T, expiry: Expiry? = nil) {
let semaphore = DispatchSemaphore(value: 0)

cache.add(key, object: object, expiry: expiry) {
cache.add(object, forKey: key, expiry: expiry) {
semaphore.signal()
}

Expand All @@ -49,7 +49,7 @@ public struct SyncHybridCache {

let semaphore = DispatchSemaphore(value: 0)

cache.object(key) { (object: T?) in
cache.object(forKey: key) { (object: T?) in
result = object
semaphore.signal()
}
Expand Down
Loading

0 comments on commit 26ea6f6

Please sign in to comment.