Skip to content

Instantly share code, notes, and snippets.

@Sonictherocketman
Created August 10, 2016 17:02
Show Gist options
  • Save Sonictherocketman/e07e62cc6b0e78e058829ebec721beac to your computer and use it in GitHub Desktop.
Save Sonictherocketman/e07e62cc6b0e78e058829ebec721beac to your computer and use it in GitHub Desktop.
An example of an NSNotificationCenter driven background updater.
/**
* A protocol that handles listening to notifications and updating model data asycronously.
*
* To use: create a class that fulfills the protocol and fill in the updateData method.
*/
@objc protocol BackgroundModelUpdater {
/**
* A notification identifier to be used to tell the updater to begin processing updates.
*/
var updateNotification: String { get set }
/**
* A notification identifier to be used to tell other instances that the models have been processed.
*/
optional var updateCompleteNotification: String { get set }
/**
* This method should perform any updates or networked behavior, then call the callback.
*/
func updateData(completionHandler: ()->())
}
extension BackgroundModelUpdater {
func configure() {
let notifications = NSNotificationCenter.defaultCenter()
notifications.addObserverForName(updateNotification, object: nil, queue: nil) { notification in
self.shouldUpdateData()
}
}
private func shouldUpdateData() {
updateData(notify)
}
private func notify() {
if let completionNotificationName = updateCompleteNotification {
let notifications = NSNotificationCenter.defaultCenter()
notifications.postNotificationName(completionNotificationName, object: nil)
}
}
}
enum MyModelUpdaterNotifications: String {
case updateNotification = "MyModelUpdater.updateNotification"
case updateCompleteNotification = "MyModelUpdater.updateCompleteNotification"
}
class MyModelUpdater: BackgroundModelUpdater {
@objc var updateNotification = MyModelUpdaterNotifications.updateNotification.rawValue
@objc var updateCompleteNotification = MyModelUpdaterNotifications.updateCompleteNotification.rawValue
@objc func updateData(completionHandler: () -> ()) {
// Do all your networking, downloading, and persisting here.
// When all of the data you need to download has finished,
// then call the completionHandler to let the rest of the app know.
completionHandler()
}
}
/**
* Your UI View Controller
*/
class MyTableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
refreshControl = UIRefreshControl()
// Pull to Refresh will trigger the download.
refreshControl?.addTarget(self,
action: #selector(MyTableViewController.refreshData),
forControlEvents: UIControlEvents.ValueChanged)
// A completion notification will be fired to let the VC know that the updates are in the database.
let notifications = NSNotificationCenter.defaultCenter()
notifications.addObserver(self,
selector: #selector(refreshTable),
name: MyModelUpdaterNotifications.updateCompleteNotification.rawValue,
object: nil)
shouldRefreshData()
}
// MARK: Refresh Methods
func shouldRefreshData() {
let notifications = NSNotificationCenter.defaultCenter()
notifications.postNotificationName(ActivityModelUpdaterNotifications.updateNotification.rawValue, object: self)
}
func refreshTable() {
self.refreshControl?.endRefreshing()
self.tableView.reloadData()
}
//...
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment