Reputation: 6526
I have an NSDictionary
which I cached. I need to implement a time-based setObject with timestamp. NSCache Class
doesn't have a setExpiry. Any help would be appreciated.
This is the extension I have so far:
import Foundation
extension NSCache {
class var sharedInstance : NSCache {
struct Static {
static let instance : NSCache = NSCache()
}
return Static.instance
}
}
I found NSCache Extension
at http://nshipster.com/nscache/ . Any easy way to implement with an expiry timestamp?
extension NSCache {
subscript(key: AnyObject) -> AnyObject? {
get {
return objectForKey(key)
}
set {
if let value: AnyObject = newValue {
setObject(value, forKey: key)
} else {
removeObjectForKey(key)
}
}
}
}
Upvotes: 1
Views: 3505
Reputation: 2537
Here is the basic approach.
PS: I haven't tested this code and I wrote it in the text editor. It may require some tweaks depending on your requirements :)
import Foundation
protocol Cacheable: class {
var expiresAt : NSDate { get set }
}
class CacheableItem : Cacheable {
var expiresAt = NSDate()
}
extension NSCache {
subscript(key: AnyObject) -> Cacheable? {
get {
if let obj = objectForKey(key) as? Cacheable {
var now = NSDate();
if now.isGreaterThanDate(obj.expiresAt) {
removeObjectForKey(key)
}
}
return objectForKey(key) as? Cacheable
}
set {
if let value = newValue {
setObject(value, forKey: key)
} else {
removeObjectForKey(key)
}
}
}
}
extension NSDate
{
func isGreaterThanDate(dateToCompare : NSDate) -> Bool
{
var isGreater = false
if self.compare(dateToCompare) == NSComparisonResult.OrderedDescending {
isGreater = true
}
return isGreater
}
}
Based on this Stack Overflow answer.
Upvotes: 4
Reputation: 438277
You can also use a timer to empty the queue:
private let ExpiringCacheObjectKey = "..."
private let ExpiringCacheDefaultTimeout: NSTimeInterval = 60
class ExpiringCache : NSCache {
/// Add item to queue and manually set timeout
///
/// - parameter obj: Object to be saved
/// - parameter key: Key of object to be saved
/// - parameter timeout: In how many seconds should the item be removed
func setObject(obj: AnyObject, forKey key: AnyObject, timeout: NSTimeInterval) {
super.setObject(obj, forKey: key)
NSTimer.scheduledTimerWithTimeInterval(timeout, target: self, selector: "timerExpires:", userInfo: [ExpiringCacheObjectKey : key], repeats: false)
}
// Override default `setObject` to use some default timeout interval
override func setObject(obj: AnyObject, forKey key: AnyObject) {
setObject(obj, forKey: key, timeout: ExpiringCacheDefaultTimeout)
}
// method to remove item from cache
func timerExpires(timer: NSTimer) {
removeObjectForKey(timer.userInfo![ExpiringCacheObjectKey] as! String)
}
}
Upvotes: 2