Last active
November 15, 2015 23:47
-
-
Save pgherveou/c0e5bd639bbdb2b5869c to your computer and use it in GitHub Desktop.
First attempt at porting FirebaseArray to swift - https://github.com/firebase/FirebaseUI-iOS
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 XCPlayground | |
| import Firebase | |
| import PromiseKit | |
| // MARK: FirebaseArrayDelegate | |
| protocol FirebaseArrayDelegate: class { | |
| func childNotFound(key: String) | |
| func childAdded(snapshot: FDataSnapshot, atIndex index: Int) | |
| func childChanged(snapshot: FDataSnapshot, atIndex index: Int) | |
| func childRemoved(snapshot: FDataSnapshot, atIndex index: Int) | |
| func childMoved(snapshot: FDataSnapshot, fromIndex: Int, toIndex: Int) | |
| } | |
| // MARK: FirebaseArray | |
| class FirebaseArray { | |
| // MARK: properties | |
| weak var delegate: FirebaseArrayDelegate? | |
| // MARK: private properties | |
| private var snapshots: [FDataSnapshot] = [] | |
| private let query: FQuery | |
| // MARK: initializers | |
| init(query: FQuery) { | |
| self.query = query | |
| initListeners() | |
| } | |
| // MARK: methods | |
| // MARK: Private methods | |
| private func indexForKey(key: String?) -> Int? { | |
| guard let key = key else { return -1 } | |
| for (index, snapshot) in snapshots.enumerate() where snapshot.key == key { return index } | |
| delegate?.childNotFound(key) | |
| return nil | |
| } | |
| private func initListeners() { | |
| query.observeEventType(.ChildAdded, andPreviousSiblingKeyWithBlock: {(snapshot, previousChildKey) in | |
| guard let previousIndex = self.indexForKey(previousChildKey) else { return } | |
| let index = previousIndex + 1 | |
| self.snapshots.insert(snapshot, atIndex: index) | |
| self.delegate?.childAdded(snapshot, atIndex: index) | |
| }) | |
| query.observeEventType(.ChildChanged, andPreviousSiblingKeyWithBlock: {(snapshot, previousChildKey) in | |
| guard let index = self.indexForKey(snapshot.key) else { return } | |
| self.snapshots[index] = snapshot | |
| self.delegate?.childChanged(snapshot, atIndex: index) | |
| }) | |
| query.observeEventType(.ChildRemoved, withBlock: {(snapshot) in | |
| guard let index = self.indexForKey(snapshot.key) else { return } | |
| self.snapshots.removeAtIndex(index) | |
| self.delegate?.childRemoved(snapshot, atIndex: index) | |
| }) | |
| query.observeEventType(.ChildMoved, andPreviousSiblingKeyWithBlock: {(snapshot, previousChildKey) in | |
| guard let fromIndex = self.indexForKey(snapshot.key) else { return } | |
| self.snapshots.removeAtIndex(fromIndex) | |
| guard let previousIndex = self.indexForKey(previousChildKey) else { return } | |
| let toIndex = previousIndex + 1 | |
| self.snapshots.insert(snapshot, atIndex: toIndex) | |
| self.delegate?.childMoved(snapshot, fromIndex: fromIndex, toIndex: toIndex) | |
| }) | |
| } | |
| } | |
| // MARK: FirebaseArray + CollectionType | |
| extension FirebaseArray: CollectionType { | |
| typealias Index = Int | |
| typealias T = FDataSnapshot | |
| var startIndex: Int { | |
| return 0 | |
| } | |
| var endIndex: Int { | |
| return snapshots.count | |
| } | |
| subscript(i: Int) -> T { | |
| return snapshots[i] | |
| } | |
| } | |
| // MARK: Reporter | |
| class Reporter: FirebaseArrayDelegate { | |
| let array: FirebaseArray | |
| init(array: FirebaseArray) { | |
| self.array = array | |
| self.array.delegate = self | |
| } | |
| func childNotFound(key: String) { | |
| print("Key not found: \(key)") | |
| } | |
| func childAdded(snapshot: FDataSnapshot, atIndex index: Int) { | |
| print("\(snapshot.key) added at \(index)") | |
| print(array.map { $0.key }) | |
| print("~~~~~") | |
| } | |
| func childChanged(snapshot: FDataSnapshot, atIndex index: Int) { | |
| print("\(snapshot.key) changed to \(index)") | |
| print(array.map { $0.key }) | |
| print("~~~~~") | |
| } | |
| func childRemoved(snapshot: FDataSnapshot, atIndex index: Int) { | |
| print("\(snapshot.key) removed at \(index)") | |
| print(array.map { $0.key }) | |
| print("~~~~~") | |
| } | |
| func childMoved(snapshot: FDataSnapshot, fromIndex: Int, toIndex: Int) { | |
| print("\(snapshot.key) moved from \(fromIndex) to \(toIndex)") | |
| print(array.map { $0.key }) | |
| print("~~~~~") | |
| } | |
| } | |
| // MARK: Demo | |
| func delay(time:Double, closure: () -> Void) { | |
| dispatch_after( | |
| dispatch_time(DISPATCH_TIME_NOW, Int64(time * Double(NSEC_PER_SEC))), | |
| dispatch_get_main_queue(), closure) | |
| } | |
| let ref = Firebase(url: "https://firenext-test2.firebaseio.com/") | |
| ref.removeValue() | |
| let array = FirebaseArray(query: ref.queryOrderedByPriority()) | |
| let reporter = Reporter(array: array) | |
| delay(0.1) { ref.childByAppendingPath("a").setValue(true, andPriority: "a") } | |
| delay(0.2) { ref.childByAppendingPath("c").setValue(true, andPriority: "c") } | |
| delay(0.3) { ref.childByAppendingPath("b").setValue(true, andPriority: "b") } | |
| delay(0.4) { ref.childByAppendingPath("c").setPriority("a") } | |
| delay(0.5) { ref.childByAppendingPath("a").removeValue() } | |
| XCPlaygroundPage.currentPage.needsIndefiniteExecution = true |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment