I am unable to post the notifications - ios

I had searched stack over flow and all sites but unable to post notifications and I need to pass data from this class to another class I need to send the bool value to have validations can anyone help me how to pass the bool value ?
here is the code for it
radioSelected = false
NotificationCenter.default.addObserver(self, selector: #selector(paymentRadioEnable(n:)), name: NSNotification.Name.init(rawValue: "notification"), object: nil)
self.shippingmethodURL()
shippingTableView.delegate = self
shippingTableView.dataSource = self
shippingTableView.rowHeight = UITableViewAutomaticDimension
shippingTableView.estimatedRowHeight = shippingTableView.rowHeight
// Initialization code
}
func paymentRadioEnable(n:NSNotification){
}
func paymentRadioAction(button : KGRadioButton) {
_ = button.center
let centralPoint = button.superview?.convert(button.center, to:self.shippingTableView)
let indexPath = self.shippingTableView.indexPathForRow(at: centralPoint!)
if button.isSelected {
} else{
chekIndex = indexPath
radioSelected = true
self.shippingTableView.reloadData()
}
}
this is another class to which I need to post the bool value to check
#IBAction func continueButtonAction(_ sender: Any) {
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "notification"), object: nil)
if radioSelected == false {
let radiobutton = SCLAlertView()
_ = radiobutton.showError("Warning", subTitle: "Please select shipping method", closeButtonTitle: "OK")
}else{
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let addtoCartVC = storyboard.instantiateViewController(withIdentifier: "payment") as! PaymentMethodViewController
self.navigationController?.pushViewController(addtoCartVC, animated: true)
}
}

You can send the data into the object at the time of posting the Notification
let data : NSDictionary = ["DataKey" : "DataValue"]
NotificationCenter.default.post(name: NSNotification.Name(rawValue:
"notification"), object: data)
And after posting , you can get the same data in notification Handler.

Related

Notification observer selector not called

I have this observer
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(GetUserID(_:)), name: Notification.Name("UserID"), object: nil)
}
and this selector function
#objc func GetUserID(_ notification: Notification){
let User = notification.object as? String
self.UserID = User
}
And I keep getting nil in UserID even though I am certain that when I get the notification it is not nil which makes me believe that the selector is not being called
You can get observer value by below method
let selectedIndex:[String: Int] = ["selectedIndex": 1]
//selectedindex = 0
// post a notification
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "SelectedSegment"), object: nil, userInfo: selectedIndex)
NotificationCenter.default.addObserver(self, selector: #selector(self.changeSegmentControlIndex(notification:)), name: Notification.Name("SelectedSegment"), object: nil)
#objc func changeSegmentControlIndex(notification: Notification) {
if let selectedIndex = notification.userInfo?["selectedIndex"] as? Int {
// do something with your image
print(selectedIndex)
}
}

Notification not triggering when view controller updated on Navigation stack changed

I'm trying to send a notification on changing the navigation stack update. But it's not triggered. Here is my code. I have a requirement to change the root view controller on button action. I'm trying the below code, but it's not working for me.
import UIKit
class SecondViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func replaceThirdViewControllerAsNavigationRoot() {
let nc = NotificationCenter.default
nc.post(name: Notification.Name("Notify"), object: nil)
self.navigationController?.viewControllers = [ThirdViewController.instance()]
}
}
class ThirdViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let nc = NotificationCenter.default
nc.addObserver(self, selector: #selector(userLoggedIn), name: Notification.Name("Notify"), object: nil)
}
#objc func userLoggedIn() {
print("-----")
}
}
extension UIViewController {
static func instance<T: UIViewController>() -> T {
let name = String(describing: self)
guard let controller = UIStoryboard.main.instantiateViewController(withIdentifier: name) as? T else {
fatalError("ViewController '\(name)' is not of the expected class \(T.self).")
}
return controller
}
}
extension UIStoryboard {
static var main: UIStoryboard {
return UIStoryboard.init(name: "Main", bundle: nil)
}
}
Thanks in advance.
The sequence of event is wrong. When you post a notification, you need to make sure that an observer already exists, otherwise the notification will be discarded.
In other words: make sure that
nc.addObserver(self, selector: #selector(userLoggedIn), name: Notification.Name("Notify"), object: nil)
runs before
nc.post(name: Notification.Name("Notify"), object: nil)

Show a button on another controller

I have two controller, one controller is controllerOne.swift, in this I receive notifications and I need when one notification arrive, show a button on controllerTwo.swift.
My code is:
ControllerOne.swift
public func websocket(token: Any){
self.ws.open("ws://"+String(APIHOST)+":"+String(port)+"/ws?token="+String(describing: token))
self.ws.event.message = { message in
let res = self.convertToDictionary(text: message as! String)
if ((res!["notification"]) != nil) {
self.count_total_notifications_ws = self.count_total_notifications_ws! + 1
let presentView = UIApplication.shared.keyWindow?.rootViewController?.presentedViewController as? SWRevealViewController
let tabbarController = presentView?.frontViewController as? UITabBarController
if (tabbarController?.selectedIndex != 0) {
tabbarController?.tabBar.items?[0].badgeValue = self.count_total_notifications_ws?.description
}else{
//Here I need to show a showNotificationsbtn button
}
}
}
}
ControllerTwo.swift
class NewDashboardViewController: UIViewController, UITableViewDataSource, UITabBarControllerDelegate, UITableViewDelegate {
//This is the button that I need show
#IBOutlet weak var showNotificationsbtn: UIButton!
#IBAction func showNotifications(_ sender: Any) {true
self.viewDidAppear(true)
showNotificationsbtn.isHidden = true
}
}
Someone know how to I can do?
Thanks for your help.
In ViewControllerOne
if ((res!["notification"]) != nil) {
self.count_total_notifications_ws = self.count_total_notifications_ws! + 1
let presentView = UIApplication.shared.keyWindow?.rootViewController?.presentedViewController as? SWRevealViewController
let tabbarController = presentView?.frontViewController as? UITabBarController
if (tabbarController?.selectedIndex != 0) {
tabbarController?.tabBar.items?[0].badgeValue = self.count_total_notifications_ws?.description
}else{
//Here I need to show a showNotificationsbtn button
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "remoNotificationArrived"), object: nil, userInfo: nil )
}
}
In ViewControllerTwo
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
DispatchQueue.main.async {
NotificationCenter.default.addObserver(self, selector: #selector(self.showButton), name: NSNotification.Name(rawValue: "remoNotificationArrived"), object: nil)
}
}
func showButton(){
showNotificationsbtn.isHidden = false
}
First hide your button.
Now to unhide that button,you have multiple options.
1. Use delgate/protocol for communicating between viewcontrollers
2. You may add an observer

tableview reloadData crashes unexpected found nil while unwrapping optional value

I'm having some trouble understanding why the reloadData() line crashes with the following error 'unexpected found nil while unwrapping optional value'(also, why is it an optional?). Basically, when user taps a button it fires an API request, second VC(recipesVC) is shown and when data is retrieved from the API, in receivedRecipes method (previous VC) I want to reloadData from recipesVC (currentVC)
As my data is correctly passed to recipesVC, I don't see why reloadData() won't work on the same VC. Could you please give me a little help with this?
thank you.
override func viewDidLoad() {
super.viewDidLoad()
let recipes = Notification.Name(rawValue: "gotRecipes")
NotificationCenter.default.addObserver(self, selector: #selector(receivedRecipes),name: recipes, object: nil)
}
#objc func receivedRecipes() {
let recipesVC = storyboard?.instantiateViewController(withIdentifier: "recipesList") as! RecipesViewController
recipesVC.recipesList = request.recipeDetails
recipesVC.recipes.reloadData()
}
#objc func receivedRecipes() {
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "recipes"), object: nil, userInfo: ["data":request.recipeDetails])
}
In your currentVC
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(receivedRecipes(notification:)),name: NSNotification.Name(rawValue: "recipes"), object: nil)
}
#objc func receivedRecipes(notification: Notification) {
recipesList = notification.userInfo
recipes.reloadData()
}
Add validation to your data:
func receivedRecipes() {
guard let details = request.recipeDetails else { return }
let recipesVC = storyboard?.instantiateViewController(withIdentifier: "recipesList") as! RecipesViewController
recipesVC.recipesList = details
recipesVC.recipes.reloadData()
}
The next tip, you can update your notification and get recipes from the notification.object, but previously you should paste them into:
let parsedRecipes = Recipes()
NotificationCenter.default.post(name: NSNotification.Name(rawValue: "gotRecipes"), object: parsedRecipes, userInfo: nil)
Also show recipesVC after it initialization with:
self.present(...) or self.navigationController?.show(...)

Perform Action when Notification is received?

I want to switch the root view in App Delegate based off when the user receives a notification. Right now, what I have works but the timing is off. As soon as I generate the notification and schedule it, the observer triggers its Selector method, changing a Boolean too soon. The Notification is set to fire 20 seconds in the future.
I'm using a singleton called StatusOverseer to guide the notifications and view switching. I put this in init():
// Notification Observation
NSNotificationCenter.defaultCenter().addObserver(self, selector: "bankDidApprove", name: "bankApproval", object: nil)
NSNotificationCenter.defaultCenter().addObserver(self, selector: "bankDidNotApprove", name: "bankNoApproval", object: nil)
This is the method in StatusOverseer to generate a notification:
func generateNotification(isGood: Bool) {
if !setNotification && userDidFinishApplication {
let currentTime = NSDate()
let fireTime = NSDate(timeInterval: 20.0, sinceDate: currentTime)
var notification = UILocalNotification()
if isGood {
notification.alertBody = "Congratulations! You've been approved!"
notificationWasGood = true
NSNotificationCenter.defaultCenter().postNotificationName("bankApproval", object: nil)
}
else {
notification.alertBody = "Bank Status is available"
notificationWasGood = false
NSNotificationCenter.defaultCenter().postNotificationName("bankNoApproval", object: nil)
}
notification.alertAction = "open"
notification.fireDate = fireTime
notification.soundName = UILocalNotificationDefaultSoundName
UIApplication.sharedApplication().scheduleLocalNotification(notification)
setNotification = true
println("Notification Set")
}
}
The selector methods:
func bankDidApprove() {
println("Banks approved")
banksDidRespond = true
notificationWasGood = true
}
func bankDidNotApprove() {
println("Banks no approved")
banksDidRespond = true
notificationWasGood = false
}
And I have this in applicationWillEnterForeground:
var so = StatusOverseer.sharedOverseer
// Decide whether or not to present the waiting view
if so.userDidFinishApplication && !StatusOverseer.sharedOverseer.banksDidRespond {
let sb = UIStoryboard(name: "Main", bundle: nil)
let vc = sb.instantiateViewControllerWithIdentifier("submitWaiting") as! UIViewController
UIApplication.sharedApplication().keyWindow?.rootViewController = vc
}
else if so.banksDidRespond {
let sb = UIStoryboard(name: "Main", bundle: nil)
if so.notificationWasGood {
let vc = sb.instantiateViewControllerWithIdentifier("approved") as! UIViewController
UIApplication.sharedApplication().keyWindow?.rootViewController = vc
}
else {
let vc = sb.instantiateViewControllerWithIdentifier("notApproved") as! UIViewController
UIApplication.sharedApplication().keyWindow?.rootViewController = vc
}
}
else if so.userDidAcceptTerms {
let sb = UIStoryboard(name: "Main", bundle: nil)
let vc = sb.instantiateViewControllerWithIdentifier("LicenseView") as! UIViewController
UIApplication.sharedApplication().keyWindow?.rootViewController = vc
}
So is there a better way I should be doing this?
Thanks!

Resources