Skip to content

Instantly share code, notes, and snippets.

View onmyway133's full-sized avatar
๐Ÿ˜‡
What you don't know is what you haven't learned

Khoa onmyway133

๐Ÿ˜‡
What you don't know is what you haven't learned
View GitHub Profile
public struct ImageWrapper: Codable {
public let image: Image
public enum CodingKeys: String, CodingKey {
case image
}
public init(image: Image) {
self.image = image
}
@onmyway133
onmyway133 / a.swift
Created June 15, 2018 08:56
a.swift
// 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
}
public class AsyncStorage {
fileprivate let internalStorage: StorageAware
public let serialQueue: DispatchQueue
init(storage: StorageAware, serialQueue: DispatchQueue) {
self.internalStorage = storage
self.serialQueue = serialQueue
}
}
// 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")
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 {
/// 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
}
/// 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.
let diskConfig = DiskConfig(name: "Floppy")
let memoryConfig = MemoryConfig(expiry: .never, countLimit: 10, totalCostLimit: 10)
let storage = try? Storage(diskConfig: diskConfig, memoryConfig: memoryConfig)
/**
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
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")