Created
June 29, 2015 17:15
-
-
Save jarsen/7d4c8e40a728d3920b18 to your computer and use it in GitHub Desktop.
This file contains hidden or 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 | |
import ReactiveCocoa | |
import Orcinus | |
import RealmSwift | |
/// Uses download signal to fetch objects from API endpoint | |
/// and adds them to the realm. It sends a notification through | |
/// its update signal every time new items are downloaded so | |
/// observers know to refresh their realm query | |
public class Fetcher<T: Object> { | |
/// Give the fetcher a name so it can be identified | |
public let name: String? | |
/// Subscribe to this signal to be notified of updates. | |
/// The signal will always send `true`. It is just so | |
/// you know when you might refresh relevant realm queries. | |
public let updateSignal: Signal<Bool, NoError> | |
private let downloadSignal: Signal<T, Error> | |
private let sink: SinkOf<Event<Bool, NoError>> | |
private let namePrefix: String | |
public var debug = false | |
public init(name: String?=nil, downloadSignal: Signal<T, Error>) { | |
self.name = name | |
self.namePrefix = name.map { "\($0) - " } ?? "" // either "MyFetcherName - " or "" | |
(updateSignal, sink) = Signal<Bool, NoError>.pipe() | |
self.downloadSignal = downloadSignal | |
self.downloadSignal.observe(error: handleError, completed: handleCompleted, interrupted: handleInterrupted, next: handleNext) | |
} | |
private func handleError(error: Error) { | |
if debug { | |
("\(namePrefix)Fetching error: \(error.nsError.localizedDescription)") | |
} | |
} | |
private func handleCompleted() { | |
if debug { | |
print("\(namePrefix)Completed.") | |
} | |
sendCompleted(sink) | |
} | |
private func handleInterrupted() { | |
if debug { | |
print("\(namePrefix)Fetching interrupted") | |
} | |
} | |
/// Adds the object to the realm and forwards the value down | |
/// through the publically exposed signal | |
private func handleNext(value: T) { | |
if debug { | |
print("\(namePrefix)Fetched: \(value)") | |
} | |
let realm = Realm() | |
realm.write { | |
realm.add(value, update: true) | |
} | |
sendNext(self.sink, true) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment