Notification Center Help

I'm trying to pass data forward from my HdVC to my FaVC with Notification Center using a button called addToFav and it does not seem to pass my data I call var item. I need a little help figuring it out a way to modify the code so my item can be passed and set to a variable currentFav I have in my FaVC.

HdVC

Code Block
class HockeyDetailVC: UITableViewController {
   
  let imageController = FetchImage()
   
  var item: CurrentPlayers? /* This object value I want in FaVC */
override func viewDidLoad() {
    super.viewDidLoad()
    NotificationCenter.default.addObserver(self,
    selector: #selector(handleFavNotification(notification:)),
    name: .passFavNotification,
    object: nil)
  }
   
  @objc func handleFavNotification(notification:Notification){
      if let theFav = notification.object as? CurrentPlayers {
        self.item = theFav
      }
    }
  
  @IBAction func addToFav(_ sender: Any) {
    let alert = UIAlertController(title: "Favourite Added 💙", message: "\(name.text ?? "") is added to favourites", preferredStyle: .alert)
    alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
    self.present(alert, animated: true, completion: nil)
    print("Favourite button Pressed")
    let passDataVC = FavouritesVC() /* I think passDataVC is supposed to be different because I use storyboard but I don't know what else it's supposed to be. */
    self.present(passDataVC, animated: true, completion:nil)
    }


FaVC

Code Block
class FavouritesVC: UITableViewController {
   
  var currentFav: CurrentPlayers? /*this is the variable I want to set my item too. */
   
  var favArr = [CurrentPlayers]()
 override func viewDidLoad() {
    super.viewDidLoad()
    if currentFav == nil {
    self.tableView.separatorStyle = UITableViewCell.SeparatorStyle.none
    } else {
    NotificationCenter.default.post(name: .passFavNotification,
    object: self.currentFav)
    favArr.append(currentFav!)
    print(currentFav!)
    }
  }

   
Answered by OOPer in 669155022
I guess you need some storage independent from FavouritesVC.

For example:
Code Block
class FavouritesManager {
static let shared = FavouritesManager()
var favArr: [CurrentPlayers] = []
func add(_ player: CurrentPlayers) {
favArr.append(player)
NotificationCenter.default.post(
name: .passFavNotification,
object: player
)
}
}


HockeyDetailVC
Code Block
class HockeyDetailVC: UITableViewController {
//...
var item: CurrentPlayers? /* This object value I want in FaVC */
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func addToFav(_ sender: Any) {
let alert = UIAlertController(title: "Favourite Added 💙", message: "\(name.text ?? "") is added to favourites", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default) {_ in
if let favPlayer = self.item {
FavouritesManager.shared.add(favPlayer)
}
})
self.present(alert, animated: true, completion: nil)
print("Favourite button Pressed")
}
//...
}


FavouritesVC
Code Block
class FavouritesVC: UITableViewController {
//var currentFav: CurrentPlayers? /*this is the variable I want to set my item too. */
var favArr: [CurrentPlayers] {
FavouritesManager.shared.favArr
}
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(
self,
selector: #selector(handleFavNotification),
name: .passFavNotification,
object: nil)
//Other settings...
//...
}
@objc
func handleFavNotification(notification: Notification) {
tableView.reloadData() // Or something else...
}
//...
}


It depends on the view hierarchy whether Notification Center works for data passing or not.
Can you illustrate the view hierarchy and the view transitions from the common ancestor VC to FavouritesVC and to HockeyDetailVC?
My common ancestor VC is connected to my HdVC through a segue and my FaVC through a bar button item and is held by a container nav controller.

My common ancestor VC is connected to my HdVC through a segue and my FaVC through a bar button item and is held by a container nav controller. 

Thanks for trying.

So, something like this?
Code Block
container nav controller
|
+ common ancestor VC ----------> HdVC ----------------> FaVC
segue bar button item


I miss something in the logic.

The notification is sent by FavoritesVC. But where is currentFav initialised ?
And why don't you simply append in HockeyDetailVC ?

In your IBAction
Code Block
@IBAction func addToFav(_ sender: Any) {
let alert = UIAlertController(title: "Favourite Added 💙", message: "\(name.text ?? "") is added to favourites", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
self.present(alert, animated: true, completion: nil)
print("Favourite button Pressed")
let passDataVC = FavouritesVC() /* I think passDataVC is supposed to be different because I use storyboard but I don't know what else it's supposed to be. */
self.present(passDataVC, animated: true, completion:nil)
}

Line 5 and next will be executed before you tap OK.
Is it what you want ?

In addition, you will probably have an error like:
2021-03-31 15:20:44.949122+0200 simpleTest[54293:11989110] [Presentation] Attempt to present <xxxx.FavouritesVC: 0x7fbfd14534c0> on <xxxx.HockeyDetailVC: 0x7fbfd3014000> (from <xxxx.HockeyDetailVC: 0x7fbfd3014000>) which is already presenting <UIAlertController: 0x7fbfd1877a00>.


I changed as follows to make it work (call the next VC in the completion of button).
FavViewID is the ID of FavouritesVC

Code Block
@IBAction func addToFav(_ sender: UIButton) {
     let alert = UIAlertController(title: "Favourite Added 💙", message: "\(name.text ?? "") is added to favourites", preferredStyle: .alert)
alert.addAction(UIAlertAction(
title: "OK",
style: UIAlertAction.Style.default,
handler: { _ in
DispatchQueue.main.async { // pour update UI
if let passDataVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "FavViewID") as? FavouritesVC {
self.present(passDataVC, animated: true, completion: nil)
}
}
}))
self.present(alert, animated: true, completion: { print("Favourite button Pressed") } )
}

Yes you described my view hierarchy perfectly. I'm going to try your solution.
Okay so your solution dismisses my HdVC but when it goes to FaVC it doesn't seem to have the data. I just see a white screen which means my transferred item is nil still.

Yes you described my view hierarchy perfectly.

Thanks for confirmation. (I assume this you is addressing @OOPer.)

Then you are doing something I cannot understand.

You say I'm trying to pass data forward from my HdVC to my FaVC with Notification Center using a button called addToFav, but
  • your button action addToFav just presents the next VC FavouritesVC, it does not send anything

(You may need to fix some parts as described in Claude31's reply, but it is another issue than does not seem to pass my data.)
  • Your FavouritesVC would try to send currentFav from FavouritesVC to HockeyDetailVC with Notification Center if currentFav is not nil

(currentFav in FavouritesVC is always nil in viewDidLoad(), so it does nothing.)

I first though that the code NotificationCenter.default.post... is sort of a test of passing something from FavouritesVC to HockeyDetailVC with Notification Center, but your description confuses me.

If you want to send something with Notification Center from HockeyDetailVC to FavouritesVC, you need to call NotificationCenter.default.post... inside the method of HockeyDetailVC,
after FavouritesVC get ready to receive it.

Or your description from my HdVC to my FaVC is just a simple mistake and you want to pass something from FavouritesVC to HockeyDetailVC?
@ ZoneX
You say:

Okay so your solution dismisses my HdVC but when it goes to FaVC it doesn't seem to have the data. I just see a white screen which means my transferred item is nil still.

What is the data you try to transfer ? Which var content ?
If it is currentFav, then I would :
Code Block
DispatchQueue.main.async { // pour update UI
if let passDataVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "FavViewID") as? FavouritesVC {
passDataVC.currentFav = item // if this is what you want to pass
self.present(passDataVC, animated: true, completion: nil)
}

Please, when you answer and there are several posts, please remind who you are replying to.
@Claude
You say:

Please, when you answer and there are several posts, please remind who you are replying to.


Your solution works and it is currentFav but I want to make a minor modification this piece of code pushes my HdVC to FavVC but I'm wondering if there's a way I can have my data be transferred without navigating to FaVC (just stay at HdVC but transfer data to FaVC)?
Code Block
self.present(passDataVC, animated: true, completion: nil)

just stay at HdVC but transfer data to FaVC

That depends on when and how you present your FavouritesVC. If it is not instantiated yet, you cannot pass anything to non-existent VC.
Accepted Answer
I guess you need some storage independent from FavouritesVC.

For example:
Code Block
class FavouritesManager {
static let shared = FavouritesManager()
var favArr: [CurrentPlayers] = []
func add(_ player: CurrentPlayers) {
favArr.append(player)
NotificationCenter.default.post(
name: .passFavNotification,
object: player
)
}
}


HockeyDetailVC
Code Block
class HockeyDetailVC: UITableViewController {
//...
var item: CurrentPlayers? /* This object value I want in FaVC */
override func viewDidLoad() {
super.viewDidLoad()
}
@IBAction func addToFav(_ sender: Any) {
let alert = UIAlertController(title: "Favourite Added 💙", message: "\(name.text ?? "") is added to favourites", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default) {_ in
if let favPlayer = self.item {
FavouritesManager.shared.add(favPlayer)
}
})
self.present(alert, animated: true, completion: nil)
print("Favourite button Pressed")
}
//...
}


FavouritesVC
Code Block
class FavouritesVC: UITableViewController {
//var currentFav: CurrentPlayers? /*this is the variable I want to set my item too. */
var favArr: [CurrentPlayers] {
FavouritesManager.shared.favArr
}
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(
self,
selector: #selector(handleFavNotification),
name: .passFavNotification,
object: nil)
//Other settings...
//...
}
@objc
func handleFavNotification(notification: Notification) {
tableView.reloadData() // Or something else...
}
//...
}


Notification Center Help
 
 
Q