Skip to content

Instantly share code, notes, and snippets.

@ryuichis
Created October 15, 2016 13:40
Show Gist options
  • Star 14 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save ryuichis/f98f0b725156e15638982458b4a6ba8f to your computer and use it in GitHub Desktop.
Save ryuichis/f98f0b725156e15638982458b4a6ba8f to your computer and use it in GitHub Desktop.
Swift 3 Struct & NSCoding
public struct Event {
public internal(set) var timeStamp: Date
public internal(set) var eventTag: String
public init(timeStamp: Date, tag: String) {
self.timeStamp = timeStamp
self.eventTag = tag
}
}
extension Event {
class Coding: NSObject, NSCoding {
let event: Event?
init(event: Event) {
self.event = event
super.init()
}
required init?(coder aDecoder: NSCoder) {
guard let timeStamp = aDecoder.decodeObject(forKey: "timeStamp") as? Date,
let eventTag = aDecoder.decodeObject(forKey: "eventTag") as? String else {
return nil
}
event = Event(timeStamp: timeStamp, tag: eventTag)
super.init()
}
public func encode(with aCoder: NSCoder) {
guard let event = event else {
return
}
aCoder.encode(event.timeStamp, forKey: "timeStamp")
aCoder.encode(event.eventTag, forKey: "eventTag")
}
}
}
extension Event: Encodable {
var encoded: Decodable? {
return Event.Coding(event: self)
}
}
extension Event.Coding: Decodable {
var decoded: Encodable? {
return self.event
}
}
var session1 = Session(startTime: Date(), endTime: Date())
session1.events.append(Event(timeStamp: Date(), tag: "test session1/event1"))
session1.events.append(Event(timeStamp: Date(), tag: "test session1/event2"))
var session2 = Session(startTime: Date(), endTime: Date())
session2.events.append(Event(timeStamp: Date(), tag: "test session2/event1"))
session2.events.append(Event(timeStamp: Date(), tag: "test session2/event2"))
session2.events.append(Event(timeStamp: Date(), tag: "test session2/event3"))
let sessions: [Session] = [session1, session2]
let data = NSKeyedArchiver.archivedData(withRootObject: sessions.encoded)
let back = (NSKeyedUnarchiver.unarchiveObject(with: data) as? [Session.Coding])?.decoded
print(back ?? "error in getting back sessions")
/*
[
Session(
startTime: 2016-10-15 13:34:45 +0000,
endTime: Optional(2016-10-15 13:34:45 +0000),
events: [
Event(timeStamp: 2016-10-15 13:34:45 +0000, eventTag: "test session1/event1"),
Event(timeStamp: 2016-10-15 13:34:45 +0000, eventTag: "test session1/event2")]),
Session(
startTime: 2016-10-15 13:34:45 +0000,
endTime: Optional(2016-10-15 13:34:45 +0000),
events: [
Event(timeStamp: 2016-10-15 13:34:45 +0000, eventTag: "test session2/event1"),
Event(timeStamp: 2016-10-15 13:34:45 +0000, eventTag: "test session2/event2"),
Event(timeStamp: 2016-10-15 13:34:45 +0000, eventTag: "test session2/event3")])]
*/
protocol Encodable {
var encoded: Decodable? { get }
}
protocol Decodable {
var decoded: Encodable? { get }
}
extension Sequence where Iterator.Element: Encodable {
var encoded: [Decodable] {
return self.filter({ $0.encoded != nil }).map({ $0.encoded! })
}
}
extension Sequence where Iterator.Element: Decodable {
var decoded: [Encodable] {
return self.filter({ $0.decoded != nil }).map({ $0.decoded! })
}
}
public struct Session {
public internal(set) var startTime: Date
public internal(set) var endTime: Date?
public internal(set) var events: [Event]
public init(startTime: Date, endTime: Date?) {
self.startTime = startTime
self.endTime = endTime
self.events = []
}
}
extension Session {
class Coding: NSObject, NSCoding {
let session: Session?
init(session: Session) {
self.session = session
super.init()
}
required init?(coder aDecoder: NSCoder) {
guard let startTime = aDecoder.decodeObject(forKey: "startTime") as? Date,
let endTime = aDecoder.decodeObject(forKey: "endTime") as? Date?,
let events = aDecoder.decodeObject(forKey: "events") as? [Event.Coding] else {
return nil
}
var decodedSession = Session(startTime: startTime, endTime: endTime)
decodedSession.events = events.decoded as! [Event]
session = decodedSession
super.init()
}
public func encode(with aCoder: NSCoder) {
guard let session = session else {
return
}
aCoder.encode(session.startTime, forKey:"startTime")
aCoder.encode(session.endTime, forKey:"endTime")
aCoder.encode(session.events.encoded, forKey:"events")
}
}
}
extension Session: Encodable {
var encoded: Decodable? {
return Session.Coding(session: self)
}
}
extension Session.Coding: Decodable {
var decoded: Encodable? {
return self.session
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment