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
You can’t perform that action at this time.