Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Using enum for getting/setting value and modification date – Inessential · Swift Structs and valueForKey:
import Swift
import Cocoa
// Properties you need as an enum - problem of key value coding is it allows you to type *anything*, typos compile fine.
enum SyncObjectPropertyName {
case Archived
case Title
}
// Protocol shared both for local and server
protocol SyncObjectReading {
var archived: Bool { get }
var archivedModificationDate: NSDate { get }
var title: String { get }
var titleModificationDate: NSDate { get }
// Conveniently returns a tuple of the value and its modification date
func propertyValueAndModificationDate(propertyName: SyncObjectPropertyName) -> (value: AnyObject, modificationDate: NSDate)
}
// Works on a SyncObjectReading instance, gets a tuple of a value and modification date for a property
func SyncObjectReading_propertyValueAndModificationDate(object: SyncObjectReading, propertyName: SyncObjectPropertyName) -> (value: AnyObject, modificationDate: NSDate) {
switch propertyName {
case .Archived:
return (object.archived, object.archivedModificationDate)
case .Title:
return (object.title, object.titleModificationDate)
}
}
// Incoming object from server
struct ServerObject: SyncObjectReading {
var archived: Bool
var archivedModificationDate: NSDate
var title: String
var titleModificationDate: NSDate
func propertyValueAndModificationDate(propertyName: SyncObjectPropertyName) -> (value: AnyObject, modificationDate: NSDate) {
return SyncObjectReading_propertyValueAndModificationDate(self, propertyName)
}
}
// Locally stored object
class LocalObject : NSObject, SyncObjectReading {
var archived: Bool
var archivedModificationDate: NSDate
var title: String
var titleModificationDate: NSDate
init(archived: Bool, archivedModificationDate: NSDate, title: String, titleModificationDate: NSDate) {
self.archived = archived
self.archivedModificationDate = archivedModificationDate
self.title = title
self.titleModificationDate = titleModificationDate
}
func propertyValueAndModificationDate(propertyName: SyncObjectPropertyName) -> (value: AnyObject, modificationDate: NSDate) {
return SyncObjectReading_propertyValueAndModificationDate(self, propertyName)
}
func setProperty(propertyName: SyncObjectPropertyName, value: AnyObject, modificationDate: NSDate) {
switch propertyName {
case .Archived:
archived = value as Bool
archivedModificationDate = modificationDate
case .Title:
title = value as String
titleModificationDate = modificationDate
}
}
func mergeProperty(propertyName: SyncObjectPropertyName, fromSyncObject syncObject:SyncObjectReading) {
let selfValueAndDate = self.propertyValueAndModificationDate(propertyName)
let externalValueAndDate = syncObject.propertyValueAndModificationDate(propertyName)
if selfValueAndDate.modificationDate.timeIntervalSinceReferenceDate < externalValueAndDate.modificationDate.timeIntervalSinceReferenceDate {
self.setProperty(propertyName, value: externalValueAndDate.value, modificationDate: externalValueAndDate.modificationDate)
}
}
}
// Example of accessing properties easily.
let localObjectA = LocalObject(archived: true, archivedModificationDate: NSDate(), title: "Note", titleModificationDate: NSDate())
let serverObjectA = ServerObject(archived: false, archivedModificationDate: NSDate(timeIntervalSinceNow: -60*60*123), title: "Note new title", titleModificationDate: NSDate(timeIntervalSinceNow: 60*60*5))
// Archived
localObjectA.propertyValueAndModificationDate(.Archived)
serverObjectA.propertyValueAndModificationDate(.Archived)
// Title
localObjectA.propertyValueAndModificationDate(.Title)
serverObjectA.propertyValueAndModificationDate(.Title)
// Merging
localObjectA.mergeProperty(.Archived, fromSyncObject: serverObjectA)
localObjectA.mergeProperty(.Title, fromSyncObject: serverObjectA)
localObjectA.archived // Should be the same as server date was earlier
localObjectA.title // Should have changed as server date was later
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment