Skip to content

Instantly share code, notes, and snippets.

@ilyapuchka
Last active September 23, 2016 20:52
Show Gist options
  • Save ilyapuchka/5f45268dc2667f6a445c8cf644b926ef to your computer and use it in GitHub Desktop.
Save ilyapuchka/5f45268dc2667f6a445c8cf644b926ef to your computer and use it in GitHub Desktop.
Swift & NSCoding
public final class Box<T> {
public let value: T
public init(value: T) {
self.value = value
}
}
public final class NSCodingBox<T: Coding>: NSObject, NSCoding {
public let value: T
public init(value: T) {
self.value = value
super.init()
}
@objc public required init?(coder aDecoder: NSCoder) {
guard let value = T.decode(with: aDecoder) else { return nil }
self.value = value
super.init()
}
@objc public func encodeWithCoder(aCoder: NSCoder) {
value.encode(with: aCoder)
}
}
public protocol Coding {
func encode(with coder: NSCoder)
static func decode(with coder: NSCoder) -> Self?
}
extension Coding {
public func archive() -> NSData {
return NSKeyedArchiver.archivedDataWithRootObject(NSCodingBox(value: self))
}
public static func unarchive(data: NSData) -> Self? {
return (NSKeyedUnarchiver.unarchiveObjectWithData(data) as? NSCodingBox<Self>)?.value
}
}
struct SomeType: Coding, Equatable {
let property: String
func encode(with coder: NSCoder) {
coder.encodeObject(property, forKey: "property")
}
static func decode(with coder: NSCoder) -> SomeType? {
guard let property = coder.decodeObjectForKey("property") as? String else { return nil }
return SomeType(property: property)
}
}
let value = SomeType(property: "value")
let data = value.archive()
let decoded = SomeType.unarchive(data)
let box = NSCodingBox<SomeType>(value: value)
let data = NSKeyedArchiver.archivedDataWithRootObject(box)
let decoded = NSKeyedUnarchiver.unarchiveObjectWithData(data) as! NSCodingBox<SomeType>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment