Last active
April 23, 2017 20:48
-
-
Save keith-kurak/c725492e2eda9c7bf62e9ea56c125af3 to your computer and use it in GitHub Desktop.
Decoupled Firebase code
This file contains 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
//1) Have a protocol that serves as a placeholder for something that is observing updates- mainly so you can unsubscribe from updates later when you no longer need them | |
protocol UpdateObserving { | |
func unsubscribe() | |
} | |
//1a) Implement that protocol for Firebase. It needs a ref that can unsubscribe and a handle to the specific subscription | |
class FirebaseObserver: UpdateObserving { | |
private var handle: UInt | |
private var firebaseReference: FIRDatabaseReference | |
init(handle: UInt, firebaseRef: FIRDatabaseReference) { | |
self.handle = handle | |
self.firebaseReference = firebaseRef | |
} | |
func unsubscribe() { | |
firebaseReference.removeObserver(withHandle: self.handle) | |
} | |
} | |
//2) FirebaseRepository.swift: Have a repository for your Firebase calls. Anything that observes returns an UpdateObserving | |
func observeRecordChanges(completionBlock: @escaping ([RecordModel]) -> ()) -> UpdateObserving { | |
let userID = FIRAuth.auth()?.currentUser?.uid | |
//super-important: you always need a ref to the specific place you're subscribing to. Otherwise you can end up shutting off other subscriptions. | |
let deepRef = FIRDatabase.database().reference().child("users").child(userID!).child("records") | |
//keep the return var from your observation | |
let handle = deepRef.observe(.value, with: {(snapshot) in | |
var records = [RecordModel]() | |
for obj in snapshot.children.allObjects as! [FIRDataSnapshot] { | |
let record = RecordModel(fromSnapshot: obj) //make an object to translate Firebase snapshots into something nice | |
records.append(record) | |
} | |
completionBlock(records) | |
}) | |
//return the observer when you're done so the consumer can unsubscribe | |
return FirebaseObserver(handle: handle, firebaseRef: deepRef) | |
} | |
//3) TableViewController.swift: subscribe to changes when your VC appears, and unsubscribe when it dissappears. | |
var records = [RecordModel]() | |
var recordObserver: UpdateObserving? | |
var repository = FirebaseRepository() | |
func viewWillAppear(_ animated: Bool) { | |
self.recordObserver = self.repository.observeRecordChanges(completionBlock: { [unowned self] (records) in | |
DispatchQueue.main.async { [unowned self] in | |
self.records = records | |
self.tableView.reloadData() | |
} | |
} | |
// don't forget to clean up after yourself or things will get slow or buggy or both // | |
func viewWillDissappear(_ animated: Bool) { | |
self.recordObserver?.unsubscribe() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment