Delegation and NSNotificationCenter
Delegate Design Pattern
- Create a delegate protocol that defines the responsibilities of the delegate.
- Create a delegate property in the delegating class to keep track of the delegate.
- Adopt and implement the delegate methods in the delegate class.
- Call the delegate from the delegating object.
Example:
// Our Delegate
protocol DudeUpdater {
func dudeDidUpdateAge(sender: Dude)
}
public class Dude: NSObject {
// Dude Delegate
var delegate: DudeUpdater?
dynamic var age = 1
private var timer: NSTimer?
override init() {
super.init()
self.timer = NSTimer.scheduledTimerWithTimeInterval(5.0, target: self,
selector: #selector(getOlder), userInfo: nil, repeats: true)
}
public func getOlder() {
self.age += 1
print(self.age)
// Dude Delegate is called here
delegate?.dudeDidUpdateAge(self)
}
}
// UIView
// This conforms to the delegate
public class DudeDisplayer: UIView, DudeUpdater {
private var dude: Dude!
private var label: UILabel!
private var myContext = 0
convenience init(dude: Dude, frame: CGRect) {
self.init(frame: frame)
// Initializes The Dude
self.dude = dude
// Sets the delegate of the dude
dude.delegate = self
self.label = UILabel(frame: CGRect(x: 50, y: 50, width: 60, height: 50))
self.label.backgroundColor = UIColor.redColor()
self.label.textAlignment = .Center
label.textColor = .whiteColor()
self.addSubview(self.label)
self.backgroundColor = .whiteColor()
}
// Delegate Method
// this is the delegate method, that updates the label with the Dude's age.
func dudeDidUpdateAge(sender: Dude){
label.text = "Age: \(String(sender.age))"
}
}
NSNotification Pattern
The basic configuration to set up a proper notification requires two parts: • a sender class that posts the notification • and a receiver class that observes the post.
Sender Class
A sender class can be any class that you want to actually post or send the notification, we do this by using NSNotificationCenter's postNotificationName.
Receiver Class
A receiver class can be any class that you want that will receive or observe notifications, we do this by using NSNotificationCenter's addObserver or addObserverName methods.
Example:
/// NSNotificationCenter
// We use this as our notification center key
let dudeNotificationKey = "dude.did.update"
public class Dude: NSObject {
dynamic var age = 1
private var timer: NSTimer?
// The Dude's NotificationCenter
let notificationCenter = NSNotificationCenter.defaultCenter()
override init() {
super.init()
self.timer = NSTimer.scheduledTimerWithTimeInterval(5.0, target: self,
selector: #selector(getOlder), userInfo: nil, repeats: true)
}
public func getOlder() {
self.age += 1
print(self.age)
// The Dude's Notification Center posts the Dude's age - the age is contained in the dictionary.
notificationCenter.postNotificationName(dudeNotificationKey, object: nil, userInfo: ["age": self.age])
}
}
// UIView
public class DudeDisplayer: UIView {
private var dude: Dude!
private var label: UILabel!
private var myContext = 0
// The DudeDisplayer's Notification Center
let notificationCenter = NSNotificationCenter.defaultCenter()
convenience init(dude: Dude, frame: CGRect) {
self.init(frame: frame)
// Initializes The Dude
self.dude = dude
// The DudeDisplayer's NotificationCenter is listening for the update, and will
// call updateLabelWithNotification when it "hears it"
notificationCenter.addObserver(self, selector: #selector(updateLabelWithNotification), name: dudeNotificationKey, object: nil)
self.label = UILabel(frame: CGRect(x: 50, y: 50, width: 80, height: 50))
self.label.backgroundColor = UIColor.redColor()
self.label.textAlignment = .Center
label.textColor = .whiteColor()
self.addSubview(self.label)
self.backgroundColor = .whiteColor()
}
// This method is called when the DudeDisplayer's NotificationCenter receives a NSNotification.
// The method takes a notification, and parses out the Dude's age from the userInfo dictionary.
// The text of the label is then updated.
func updateLabelWithNotification(notification: NSNotification) {
let userInfo = notification.userInfo as! [String: Int]
label.text = "Age: \(userInfo["age"]!)"
}
}