EasyStash is an easy and lightweight persistence framework in Swift. With simple abstraction over NSCache
and FileManager
, it saves us from tedious work of saving and loading objects. There are no clever async, expiry handling or caching strategy for now, just save and load.
- Swift 5
- Support iOS, macOS, tvOS, watchOS
- Synchronous APIs with explicit try catch
- Persist UIImage/NSImage
- Persist Codable objects, including primitive types
- Persist Data
- Test coverage
The main and only class is Storage
which encapsulates memory and disk cache. All operations involving disk are error prone, we need to handle error explicitly.
With Options
, we can customize folder
name, searchPathDirectory
, encoder
and decoder
for Codable
. By default, folder
and searchPathDirectory
specify that files will be saved at /Library/Application Support/{BUNDLE_ID}/Default/
var storage: Storage? = nil
var options: Options = Options()
options.folder = "Users"
storage = try? Storage(options: options)
do {
try storage?.save(image, forKey: "image")
try storage?.save(users, forKey: "codable")
} catch {
print(error)
}
Memory cache is checked first before doing disk operations, so we won't hit disk that often.
Works for both UIImage and NSImage. Because image and data loading uses the same signatures, we need to explicitly specify type
try storage.save(image, forKey: "image")
let loadedImage: UIImage = try storage.load(forKey: "image")
Uses JSONEncoder
and JSONDecoder
under the hood to serialize and deserialize to and from Data
let user = User(name: "A", age: 10)
let cities = [City(name: "Oslo"), City(name: "New York")]
try storage.save(users, forKey: "user")
try storage.save(cities, forKey: "cities")
let loadedUser = try storage.load(forKey: "user", as: User.self)
let loadedCities = try storage.load(forKey: "cities", as: [City].self)
try storage.save(object: data, forKey: "data")
let loadedData: Data = try storage.load(forKey: "data")
Although primitives like Int, String, Bool
conform to Codable
, they can't be serialized into Data
using JSONEncoder
because json needs root object. This framework handles this case, so you can just save and load as normal
try storage.save(100, forKey: "an int")
try storage.save(isLoggedIn, forKey: "a boolean")
EasyStash includes some helpful functions to check file and folder within its Storage
.
Check if file exists
try storage.exists(forKey: "has_updated_profile")
Remove file
try storage.remove(forKey: "a flag")
Remove all files
try storage.removeAll()
List all files. Each file has name
, url
, modificationDate
and size
information
let files = try storage.files()
Check folder size
let size = try storage.folderSize()
Check if folder has content
try storage.isEmpty()
Remove files based on predicate. This is useful when we want to clear expired objects, or objects based certain criteria.
try storage.removeAll(predicate: { $0.modificationDate < migrationDate })
EasyStash
is designed to be synchronous. If we want to do async, it's easy as using DispatchQueue
DispatchQueue.global().async {
do {
try storage.save(largeImage, forKey: "large_image")
} catch {
}
}
EasyStash is available through CocoaPods. To install it, simply add the following line to your Podfile:
pod 'EasyStash'
EasyStash is also available through Carthage. To install just write into your Cartfile:
github "onmyway133/EasyStash"
EasyStash is also available through Swift Package Manager. Add EasyStash as a dependency to your Package.swift. For more information, please see the Swift Package Manager documentation.
.package(url: "https://github.com/onmyway133/EasyStash", from: "1.1.8")
EasyStash can also be installed manually. Just download and drop Sources
folders in your project.
Khoa Pham, [email protected]
We would love you to contribute to EasyStash, check the CONTRIBUTING file for more info.
EasyStash is available under the MIT license. See the LICENSE file for more info.