I'm trying to pass data between tab bar controllers for the firts time, but it doesn't work. First Controller:
class FirstViewController: UIViewController {
@IBOutlet weak var sentNotificationLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector: "updateNotificationSentLabel:", name: mySpecialNotificationKey, object: nil)
}
@IBAction func notify() {
NSNotificationCenter.defaultCenter().postNotificationName(mySpecialNotificationKey, object: nil, userInfo:["message":"Something"])
}
func updateNotificationSentLabel(notification:NSNotification) {
let userInfo:Dictionary<String,String!> = notification.userInfo as Dictionary<String,String!>
let messageString = userInfo["message"]
sentNotificationLabel.text = messageString
}
}
Here it works ok, the sentNotificationLabel.text is "Something"
Second Controller is similiar, but he's not receiving any notification.
class SecondViewController: UIViewController {
@IBOutlet weak var notificationLabel: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
NSNotificationCenter.defaultCenter().addObserver(self, selector: "updateLabel:", name: mySpecialNotificationKey, object: nil)
}
func updateLabel(notification:NSNotification) {
let userInfo:Dictionary<String,String!> = notification.userInfo as Dictionary<String,String!>
let messageString = userInfo["message"]
notificationLabel.text = messageString
}
}
What I am doing wrong? How to change that?
The problem occurs because you are sending the message before the second view controller is registered.
NSNotificationCenter
doesn't support sticky notifications - in other words, the message won't be cached. If no-one is listening at the very moment the notification is sent, it's just gone.
The easiest fix is to register your SecondViewController
for notification in initialiser. However, than the UILabel is not yet loaded - we are before viewDidLoad
callback. The solution is to cache the received message locally and use it to set the label text when it's ready.
class SecondViewController: UIViewController {
@IBOutlet weak var notificationLabel: UILabel!
var cachedMessage : String? = nil
required init(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "updateLabel:", name: mySpecialNotificationKey, object: nil)
}
override func viewDidLoad() {
if let cachedMessage = cachedMessage {
notificationLabel.text = cachedMessage
}
}
func updateLabel(notification:NSNotification) {
let userInfo:Dictionary<String,String!> = notification.userInfo as Dictionary<String,String!>
let messageString = userInfo["message"]
if let notificationLabel = notificationLabel {
notificationLabel.text = messageString
} else {
cachedMessage = messageString
}
}
}
Since controllers are being initialised before they are being displayed, the message should be delivered properly.