Skip to content

Instantly share code, notes, and snippets.

@khanlou
Created December 16, 2016 01:36
Show Gist options
  • Select an option

  • Save khanlou/c5b6b966223afa3b4449fb683a0d8dfc to your computer and use it in GitHub Desktop.

Select an option

Save khanlou/c5b6b966223afa3b4449fb683a0d8dfc to your computer and use it in GitHub Desktop.
import Foundation
final class Atomic<T> {
private let queue = DispatchQueue(label: "com.atomic.queue", attributes: [.concurrent])
private var value: T {
get {
return queue.sync {
return self.value
}
}
set {
queue.async(flags: .barrier) {
self._value = newValue
}
}
}
var _value: T
init(value: T) {
_value = value
}
}
struct StorageLocation {
let filename: String
var fileManager: FileManager {
return FileManager.default
}
var path: String {
return storageLocation?.path ?? ""
}
var storageLocation: URL? {
return generalStoreDirectory?.appendingPathComponent(sanitizedName)
}
private var generalStoreDirectory: URL? {
let URLs = fileManager.urls(for: .documentDirectory, in: .userDomainMask)
return URLs.first
}
private var sanitizedName: String {
return filename
.components(separatedBy: invalidFilenameCharacters)
.joined()
.replacingOccurrences(of: " ", with: "-")
}
let invalidFilenameCharacters = CharacterSet(charactersIn: ":/\\?%*|\"<>")
}
final class Persistent<T: NSCoding> {
let location: StorageLocation
let defaultValue: T
var value: T {
get {
return NSKeyedUnarchiver.unarchiveObject(withFile: location.path) as? T ?? defaultValue
}
set {
NSKeyedArchiver.archiveRootObject(value, toFile: location.path)
}
}
init(location: StorageLocation, defaultValue: T) {
self.location = location
self.defaultValue = defaultValue
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment