Cache
Cache
In general, cache provides temporary storage for items that are expensive to create or load, for example via remote network calls. Because the cache has limited storage capacity, any new item added to a full cache requires an item first be removed. The cache implementation and “cache replacement policy” specifies which item is removed.
Caching
The Caching
protocol declares the basic operations an implementer must support.
The protocol is generic; the types stored in the cache are unspecified.
The implementers of the cache however can specify restrictions for the types.
Default implementations of the Cache protocol provided with the SDK are: MemoryCache
, SecureStoreCache
, and with CompositeCache
a multilevel cache.
CodableCaching
The CodableCaching
protocol declares the basic operations an implementer must support.
The protocol is generic; can be used with any Hashable
and Equatable
type as KeyType.
The functions are also generic, they receive types which are conforming to Codable
protocol.
Implementers of the CodableCaching
has to provide a coder object which should conform to CoderProtocol
, and a Cache
which should conform to Caching
.
Default implementation of the CodableCaching
protocol provided with the SDK is: CodableCache
.
Existing caches also can be used with the new CodableCache
. The CodableCache
should be initialized with a Cache
conforming to Caching
protocol.
The cache related operations should be called on CodableCache
, then the CodableCache
object will encode/decode data. If the encoding/decoding is possible, the object will call the similar function of the received Cache
to handle the entry.
MemoryCache
MemoryCache stores ValueType*s in memory associated with *KeyType. Currently the Least Recently Used (LRU) cache replacement policy is implemented.
// create a memory cache with the given cache limits
let cache = MemoryCache<String, Data>(maximumNumberOfEntries: 2, maximumCost: 0)
let dataValue: Data = ...
let key: String = ...
let cost: Int = ...
// save the value in the cache for the key associated with the cost.
cache.set(value: dataValue, forKey: key, withCost: cost)
// retrieves the entry for the given key
let entry = cache.entry(forKey: key)
//retrieves the value for the given key
let value = cache.value(forKey: key)
//removes all items from the cache
cache.removeAllValues()
Using MemoryCache
as part of CodableCache
:
// create codable cache with memory cache
let cache = CodableCache(cache: MemoryCache<String, NSData>(maximumNumberOfEntries: 2, maximumCost: 0))
let dataValue: Data = ...
let key: String = ...
let cost: Int = ...
do {
// save the value in the cache for the key associated with the cost.
try cache.put(dataValue, for: key, with: cost)
// retrieves the entry for the given key
let cachedEntry = try cache.entry(Data.self, for: key)
// retrieves the value for the given key
let data = try cache.get(Data.self, for: key)
} catch {
// error handling
}
// removes a value from cache
cache.remove(for: key)
// removes all items from the cache
cache.removeAllValues()
SecureStoreCache
SecureStoreCache
stores elements in SecureStorage, with KeyType bound to String
.
Currently the Least Recently Used (LRU) cache replacement policy is implemented.
let fileName: String = ... // file name for the secure database store
let tableName: String = ... // table name for cache
let encryptionKey = ... // secure database store encryption key
// create a new secure database store
var store = SecureDatabaseStore(databaseFileName: fileName)
// open the store using the encryption key
try store?.open(with: encryptionKey)
// create a secure store with the given cache limits
let cache = SecureStoreCache<NSData>(maximumNumberOfEntries: 10, maximumCost: 5, secureStore: store!, tableName: tableName)
let dataValue: Data = ...
let key: String = ...
let cost: Int = ...
let value: NSData = NSData(data: dataValue)
// save the value in the cache for the key associated with the cost.
cache.set(value: value, forKey: key, withCost: cost)
// retrieves the entry for the given key
let entry = cache.entry(forKey: key)
//retrieves the value for the given key
let value = cache.value(forKey: key)
//removes all items from the cache
cache.removeAllValues()
Using SecureStoreCache
as part of CodableCache
:
// create codable cache with secure store cache
let store = store = SecureDatabaseStore(databaseFileName: "SampleFileName")
let cache = SecureStoreCache<NSData>(maximumNumberOfEntries: 2, maximumCost: 10, secureStore: store, tableName: "SamleTableName")
let codableCache = CodableCache(cache: cache)
let dataValue: Data = ...
let key: String = ...
let cost: Int = ...
do {
// save the value in the cache for the key associated with the cost.
try codableCache.put(dataValue, for: key, with: cost)
// retrieves the entry for the given key
let cachedEntry = try codableCache.entry(Data.self, for: key)
// retrieves the value for the given key
let data = try codableCache.get(Data.self, for: key)
} catch {
// error handling
}
// removes a value from cache
codableCache.remove(for: key)
// removes all items from the cache
codableCache.removeAllValues()
CompositeCache
CompositeCache is a multi-level cache container. It stores Caching implementations which must have the same KeyType and ValueType types and use them according to a well defined rule. The caches are used in a chain: if one cache doesn’t hold the necessary data the next is queried - so the order of the caches are important. An item found in an underlying level is added to all the preceding caches. The caches are appended to the end of the chain. When a value is cleared from a cache because free space is needed to store a new value, the removed value is not added to lower level caches.
let firstCache = MemoryCache<String, NSData>(maximumNumberOfEntries: 3, maximumCost: 0)
let secondCache = SecureStoreCache<NSData>(maximumNumberOfEntries: 6, maximumCost: 0, secureStore: store!, tableName: tableName)
compositeCache.addCache(firstCache)
compositeCache.addCache(secondCache)
Using CompositeCache
as part of CodableCache
:
// create codable cache with secure store cache
let firstCache = MemoryCache<String, NSData>(maximumNumberOfEntries: 3, maximumCost: 0)
let secondCache = SecureStoreCache<NSData>(maximumNumberOfEntries: 6, maximumCost: 0, secureStore: store!, tableName: tableName)
let compositeCache = CompositeCache<String, NSData>()
compositeCache.addCache(firstCache)
compositeCache.addCache(secondCache)
let codableCache = CodableCache(cache: compositeCache)
let dataValue: Data = ...
let key: String = ...
let cost: Int = ...
do {
// save the value in the cache for the key associated with the cost.
try codableCache.put(dataValue, for: key, with: cost)
// retrieves the entry for the given key
let cachedEntry = try codableCache.entry(Data.self, for: key)
// retrieves the value for the given key
let data = try codableCache.get(Data.self, for: key)
} catch {
// error handling
}
// removes a value from cache
codableCache.remove(for: key)
// removes all items from the cache
codableCache.removeAllValues()
Cache component Logger ID
This component uses the following name prefix for logging: ‘SAP.Foundation.Cache’
-
CacheEntry
CacheEntry is a simple type used by the Cache to return data to caller. This structure is not necessarily used by the cache internally to store data.
Declaration
Swift
public struct CacheEntry<EntryValueType>
-
Caching
Specifies the basic operations a cache implementation should support. In general the Cache is a key/value store. The stored items can be automatically removed from the cache when the cache reaches the maximum storage capacity. For each item in the cache a cost value can be specified. Cost is an arbitrary value (can be the size of the data for example). The behavior how the cost is handled implementation dependent. Caching is a generic protocol meaning the KeyType and ValueType can be arbitrariry selected.
See moreDeclaration
Swift
public protocol Caching
-
Implementation for CodableCache Stores each instance as
See moreData
in thecache
usingcoder
for encoding/decoding. The CodableCache instance is not thread safe. Using directly from multiple threads can lead to unexpected behaviors.Declaration
Swift
open class CodableCache<Cache> : CodableCaching where Cache : Caching, Cache.ValueType == NSData
-
Protocol to support Codable protocol with Cache
See moreDeclaration
Swift
public protocol CodableCaching
-
CompositeCache
CompositeCache is a multilevel cache container. It stores Caching implementations which has to have the same KeyType and ValueType types and use them according to a well defined rule.
let firstCache = MemoryCache<String, NSData>(maximumNumberOfEntries: 3, maximumCost: 0) let secondCache = SecureStoreCache<NSData>(maximumNumberOfEntries: 6, maximumCost: 0, secureStore: store!, tableName: tableName) compositeCache.addCache(firstCache) compositeCache.addCache(secondCache)
The caches are used in a chain: if one cache doesn’t hold the necessary data the next will be queried - so the order of the caches are important. The item which was found in an underlying level will be added to all the preceding caches. The caches are appended to the end of the chain. When a value cleared from a cache because free space is needed to store a new value, the removed value won’t be added to lower level caches.
See moreDeclaration
Swift
open class CompositeCache<CompositeCacheKeyType, CompositeCacheValueType> : Caching
-
MemoryCache
MemoryCache stores ValueType*s in memory associated with *KeyType. Currently the Least Recently Used (LRU) cache replacement policy is implemented. Generic parameters:
See more// create a memory cache with the given cache limits let cache = MemoryCache<String, Data>(maximumNumberOfEntries: 2, maximumCost: 0) let dataValue: Data = ... let key: String = ... let cost: Int = ... // save the value in the cache for the key associated with the cost. cache.set(value: dataValue, forKey: key, withCost: cost) // retrieves the entry for the given key let entry = cache.entry(forKey: key) //retrieves the value for the given key let value = cache.value(forKey: key) //removes all items from the cache cache.removeAllValues()
Declaration
Swift
open class MemoryCache<Key, Value> : Caching where Key : Hashable
Parameters
Key
the type used as a key in the cache
Value
the type to store in the cache
-
SecureStoreCache
SecureStoreCache stores Strings in SecureStorage with KeyType. Currently the Least Recently Used (LRU) cache replacement policy is implemented. Generic parameters:
See morelet fileName: String = ... // file name for the secure database store let tableName: String = ... // table name for cache let let encryptionKey = ... // secure database store encryption key // create a new secure database store var store = SecureDatabaseStore(databaseFileName: fileName) // open the store using the encryption key try store?.open(with: encryptionKey) // create a secure store cache with the given cache limits let cache = SecureStoreCache<NSData>(maximumNumberOfEntries: 10, maximumCost: 5, secureStore: store!, tableName: tableName) let dataValue: Data = ... let key: String = ... let cost: Int = ... let value: NSData = NSData(data: dataValue) // save the value in the cache for the key associated with the cost. cache.set(value: value, forKey: key, withCost: cost) // retrieves the entry for the given key let entry = cache.entry(forKey: key) //retrieves the value for the given key let value = cache.value(forKey: key) //removes all items from the cache cache.removeAllValues()
Declaration
Swift
open class SecureStoreCache<Value> : Caching where Value : NSCoding
Parameters
Key
the type used as a key in the cache
Value
the type to store in the cache, Note: Value implements NSCoding, see this: https://developer.apple.com/library/ios/referencelibrary/GettingStarted/DevelopiOSAppsSwift/Lesson10.html Note: SecureDatabaseStoreProtocol instance of SecureStoreCache should be stored in “Library/Caches/” folder by default.