-
-
Save stepanhruda/cf813d75b4cdf4e1c18c to your computer and use it in GitHub Desktop.
Immutable values and iOS
This file contains 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
import Foundation | |
protocol Identifiable { | |
typealias IdentifierType: Hashable, Serializable | |
var identifier: IdentifierType { get } | |
} | |
func isTheSameIdentity<T: Identifiable>(a: T, b: T) -> Bool { | |
return a.identifier == b.identifier | |
} | |
class IdentityStore<V: Identifiable where V: Serializable> { | |
private var defaults: NSUserDefaults | |
private var key: String | |
init(key: String) { | |
self.defaults = NSUserDefaults.standardUserDefaults() | |
self.key = key | |
let contents: AnyObject? = defaults.objectForKey(key) | |
if contents == nil { | |
defaults.setObject([:], forKey: key) | |
} | |
} | |
private var storage: [V.IdentifierType:V] { | |
get { | |
let dictionary = defaults.objectForKey(key) as NSDictionary | |
return deserializeNSDictionary(dictionary, V.self) | |
} | |
set { defaults.setObject(serializeSwiftDictionary(newValue), forKey: key) } | |
} | |
func all() -> [V] { | |
return storage.values.array | |
} | |
func add(value: V) { | |
storage[value.identifier] = value | |
} | |
func remove(value: V) { | |
removeForIdentifier(value.identifier) | |
} | |
func removeForIdentifier(identifier: V.IdentifierType) { | |
storage[identifier] = nil | |
} | |
func latest(value: V) -> V? { | |
return latestForIdentifier(value.identifier) | |
} | |
func latestForIdentifier(identifier: V.IdentifierType) -> V? { | |
return storage[identifier] | |
} | |
} | |
protocol Serializable { | |
func serialize() -> NSObject | |
class func deserialize(serialized: NSObject) -> Self | |
} | |
extension Dictionary { | |
init(pairs: [Element]) { | |
self.init() | |
for (k, v) in pairs { | |
self[k] = v | |
} | |
} | |
} | |
func serializeSwiftDictionary<I: Serializable, V: Serializable>(source: [I:V]) -> NSDictionary { | |
let serializedPairs = map(source) { (key, value) in (key.serialize(), value.serialize()) } | |
return Dictionary(pairs: serializedPairs) | |
} | |
func deserializeNSDictionary<V: Serializable where V: Identifiable>(source: NSDictionary, serializable: V.Type) -> [V.IdentifierType:V] { | |
let deserializedPairs = map(source) { (key, value) in (V.IdentifierType.deserialize(key as NSObject) , V.deserialize(value as NSObject)) } | |
return Dictionary(pairs: deserializedPairs) | |
} |
This file contains 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
struct Person { | |
var socialSecurityNumber: String | |
var age: Int | |
var salary: Int | |
func giveRaise() -> Person { | |
return Person(socialSecurityNumber: socialSecurityNumber, age: age, salary: salary + 10000) | |
} | |
} | |
extension Person: Equatable {} | |
func ==(lhs: Person, rhs: Person) -> Bool { | |
return lhs.socialSecurityNumber == rhs.socialSecurityNumber | |
&& lhs.age == rhs.age | |
&& lhs.salary == rhs.salary | |
} | |
extension Person: Identifiable { | |
typealias IdentifierType = String | |
var identifier: String { get { return socialSecurityNumber } } | |
} | |
extension String: Serializable { | |
func serialize() -> NSObject { | |
return self | |
} | |
static func deserialize(serialized: NSObject) -> String { | |
return serialized as String | |
} | |
} | |
extension Person: Serializable { | |
func serialize() -> NSObject { | |
return [ | |
"socialSecurityNumber": socialSecurityNumber, | |
"age": age, | |
"salary": salary | |
] | |
} | |
static func deserialize(serialized: NSObject) -> Person { | |
let dictionary = serialized as NSDictionary | |
let person = Person( | |
socialSecurityNumber: dictionary["socialSecurityNumber"] as String, | |
age: dictionary["age"] as Int, | |
salary: dictionary["salary"] as Int) | |
return person | |
} | |
} | |
func personStore() -> IdentityStore<Person> { | |
return IdentityStore<Person>(key: "employees") | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment