๐
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public struct ImageWrapper: Codable { | |
public let image: Image | |
public enum CodingKeys: String, CodingKey { | |
case image | |
} | |
public init(image: Image) { | |
self.image = image | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// WARNING: This does not compile | |
extension UIImage: Codable { | |
// 'required' initializer must be declared directly in class 'UIImage' (not in an extension) | |
public required init(from decoder: Decoder) throws { | |
let container = try decoder.singleValueContainer() | |
let data = try container.decode(Data.self) | |
guard let image = UIImage(data: data) else { | |
throw MyError.decodingFailed | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class AsyncStorage { | |
fileprivate let internalStorage: StorageAware | |
public let serialQueue: DispatchQueue | |
init(storage: StorageAware, serialQueue: DispatchQueue) { | |
self.internalStorage = storage | |
self.serialQueue = serialQueue | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Save to storage | |
try? storage.setObject(10, forKey: "score") | |
try? storage.setObject("Oslo", forKey: "my favorite city", expiry: .never) | |
// Load | |
let score = try? storage.object(ofType: Int.self, forKey: "score") | |
let favoriteCharacter = try? storage.object(ofType: String.self, forKey: "my favorite city") | |
// Check if an object exists | |
let hasFavoriteCharacter = try? storage.existsObject(ofType: String.self, forKey: "my favorite city") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public extension StorageAware { | |
func object<T: Codable>(ofType type: T.Type, forKey key: String) throws -> T { | |
return try entry(ofType: type, forKey: key).object | |
} | |
func existsObject<T: Codable>(ofType type: T.Type, forKey key: String) throws -> Bool { | |
do { | |
let _: T = try object(ofType: type, forKey: key) | |
return true | |
} catch { |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// A protocol used for saving and loading from storage | |
public protocol StorageAware { | |
func object<T: Codable>(ofType type: T.Type, forKey key: String) throws -> T | |
func entry<T: Codable>(ofType type: T.Type, forKey key: String) throws -> Entry<T> | |
func removeObject(forKey key: String) throws | |
func setObject<T: Codable>(_ object: T, forKey key: String, expiry: Expiry?) throws | |
func existsObject<T: Codable>(ofType type: T.Type, forKey key: String) throws -> Bool | |
func removeAll() throws | |
func removeExpiredObjects() throws | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// Manage storage. Use memory storage if specified. | |
/// Synchronous by default. Use `async` for asynchronous operations. | |
public class Storage { | |
/// Used for sync operations | |
fileprivate let sync: StorageAware | |
/// Storage used internally by both sync and async storages | |
private let interalStorage: StorageAware | |
/// Initialize storage with configuration options. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let diskConfig = DiskConfig(name: "Floppy") | |
let memoryConfig = MemoryConfig(expiry: .never, countLimit: 10, totalCostLimit: 10) | |
let storage = try? Storage(diskConfig: diskConfig, memoryConfig: memoryConfig) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
Helper enum to work with JSON arrays and dictionaries. | |
*/ | |
public enum JSON { | |
/// JSON array | |
case array([Any]) | |
/// JSON dictionary | |
case dictionary([String : Any]) | |
/// Converts value to Any |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let cache = SpecializedCache<JSON>(name: "JSONCache") | |
// Dictionary | |
cache.async.addObject(JSON.dictionary(["key": "value"]), forKey: "dictionary") | |
cache.async.object(forKey: "dictionary") { json in | |
print(json?.object) | |
} | |
// Array | |
cache.async.addObject(JSON.array([["key1": "value1"]]), forKey: "array") |