In App Settings

Hi,
Something weird is going on with my code. I want it so when someone allows me to send notifications, if they go into my setting view controller to see that toggled on. Here is a link to my project: https://www.icloud.com/iclouddrive/0PDX_ZK3kyamqHjV8-hlDhZbw#Riddle_Wednesday
Thanks in advance!
Please post the relevant part of code here as well.
Home ViewController:
Code Block //
import UIKit
import SafariServices
import UserNotifications
class Home: UIViewController {
    
    
    @IBOutlet weak var leadingHome: NSLayoutConstraint!
    @IBOutlet weak var trailingHome: NSLayoutConstraint!
    
    var menuOut = false
    
    static var riddleNotification = Bool()
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //Ask for Notification Permision
        let center = UNUserNotificationCenter.current()
        
        center.requestAuthorization(options: [.alert, .sound]) { (granted, error) in
        }
        
        func riddleNotification() {
            
            //Notification Content
            let content = UNMutableNotificationContent()
            content.title = "Check out this weeks riddle!"
            content.body = "This weeks riddle is..."
            content.categoryIdentifier = "riddle"
            
            //Notification Trigger
            let date = Date().addingTimeInterval(5)
            
            var dateComponents = DateComponents()
            //dateComponents.hour = 9
            //dateComponents.minute = 30
            //dateComponents.weekday = 4 //Wednesday
            let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true)
            
            //Create Request
            
            let uuidString = UUID().uuidString
            let request = UNNotificationRequest(identifier: uuidString, content: content, trigger: trigger)
            
            //Register Request
            center.add(request) { (error) in
                //Check the parameter and handle any errors
        }
        }
        
        
        if let value = UDM.shared.defaults.value(forKey: "riddleNotification") as? Bool {
            Home.riddleNotification = value
        }
       if Home.riddleNotification == true {
        riddleNotification()
       }
       else if Home.riddleNotification == false {
               print("no riddle notification scheduled")
       }
        else {
        
        let isRegisteredForRemoteNotifications = UIApplication.shared.isRegisteredForRemoteNotifications
        if isRegisteredForRemoteNotifications {
             // User is registered for notification
            Home.riddleNotification = true
            UDM.shared.defaults.setValue(Home.riddleNotification, forKey: "riddleNotification")
        }
        else {
             // Show alert user is not registered for notification
            Home.riddleNotification = false
            UDM.shared.defaults.setValue(Home.riddleNotification, forKey: "riddleNotification")
        }
           riddleNotification()
        }
       }
    
    @IBAction func Riddles(_ sender: Any) {
        let vc = SFSafariViewController(url: URL(string: "https://riddles.com")!)
        
        present(vc, animated: true)
    }
    
    @IBAction func RiddlesandAnswers(_ sender: Any) {
        let vc = SFSafariViewController(url: URL(string: "https://riddlesandanswers.com")!)
        
        present(vc, animated: true)
    }
    
    @IBAction func menuTappedHome(_ sender: Any) {
        
        if menuOut == false {
            leadingHome.constant = 150
            trailingHome.constant = -150
            menuOut = true
        }
        else {
            leadingHome.constant = 0
            trailingHome.constant = 0
            menuOut = false
        }
        UIView.animate(withDuration: 0.2, delay: 0.0, options: .curveEaseIn, animations: {
            self.view.layoutIfNeeded()
        }) { (animationComplete) in
            print("The animation is complete")
        }
    }
    
}
class UDM {
    
    static let shared = UDM()
    
    let defaults = UserDefaults(suiteName: "com.riddlewednesday.saved.data")!
    
}

Settings ViewController:
Code Block //
import UIKit
class Settings: UIViewController {
    
    @IBOutlet weak var leading_Settings: NSLayoutConstraint!
    @IBOutlet weak var trailing_Settings: NSLayoutConstraint!
    @IBOutlet var riddleSwitch: UISwitch!
    
    var menuOut = false
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        if Home.riddleNotification == true {
            riddleSwitch.setOn(true, animated: true)
        }
        
        if Home.riddleNotification == false {
            riddleSwitch.setOn(false, animated: true)
        }
    }
    
    @IBAction func menuTappedSettings(_ sender: Any) {
        
        if menuOut == false {
            leading_Settings.constant = 150
            trailing_Settings.constant = -150
            menuOut = true
        }
        else {
            leading_Settings.constant = 0
            trailing_Settings.constant = 0
            menuOut = false
        }
        UIView.animate(withDuration: 0.2, delay: 0.0, options: .curveEaseIn, animations: {
            self.view.layoutIfNeeded()
        }) { (animationComplete) in
            print("The animation is complete")
        }
}
    @IBAction func riddleSwitchDidChange(_ sender: Any) {
        if riddleSwitch.isOn {
        
            Home.riddleNotification = true
            UDM.shared.defaults.setValue(Home.riddleNotification, forKey: "riddleNotification")
            }
        else {
            Home.riddleNotification = false
            UDM.shared.defaults.setValue(Home.riddleNotification, forKey: "riddleNotification")
        }
    }
    
}



Can you explain the steps to reproduce the behavior which you think is weird:
  • Steps to reproduce

  • What you expect with the steps

  • What you actually get with the steps


By the way, I can find many weird codings in your code shown:

Home ViewController:
  • static var riddleNotification = Bool() (26) -- Why using static? Why aren't you specifying the initial value explicitly?

  • center.requestAuthorization (44) -- Why the completion handler is empty?

  • func riddleNotification() { (50) -- Why making it nested inside viewDidLoad()? And better avoid the same name as property.

  • else { (126) ... } (154) -- The else block would never be executed.

  • Riddles(_:) (160), RiddlesandAnswers(_:) (174) -- Why using Capitalized names?

Settings ViewController:
  • leading_Settings (10), trailing_Settings (12) -- Why snake case?

  • if Home.riddleNotification == true { (28) ... } (40) -- Why don't you write it simply riddleSwitch.setOn(Home.riddleNotification, animated: true)?

  • if riddleSwitch.isOn { (84) ... } (100) -- Why don't you write it simply:

Code Block
Home.riddleNotification = riddleSwitch.isOn
UDM.shared.defaults.setValue(riddleSwitch.isOn, forKey: "riddleNotification")

And why do you have Home.riddleNotification and UserDefaults separately if they need to be synchronized to the same value?

Some of them are just sort of convention things and may not be affecting your weird behavior, so you have no need to answer to all of the questions, but your code looks really weird for me.
I think I figured it out. When I initially determine if they allowed notifications something in there isn’t correct. I need code asking if they allowed local notifications, but I can’t find any. Ideas?
When you paste code, please use Paste And Match Style to avoid all the blank lines that make code very hard to read.

Code Block
import UIKit
import SafariServices
import UserNotifications
class Home: UIViewController {
@IBOutlet weak var leadingHome: NSLayoutConstraint!
@IBOutlet weak var trailingHome: NSLayoutConstraint!
var menuOut = false
static var riddleNotification = Bool()
override func viewDidLoad() {
super.viewDidLoad()
//Ask for Notification Permision
let center = UNUserNotificationCenter.current()
center.requestAuthorization(options: [.alert, .sound]) { (granted, error) in
}
func riddleNotification() {
//Notification Content
let content = UNMutableNotificationContent()
content.title = "Check out this weeks riddle!"
content.body = "This weeks riddle is..."
content.categoryIdentifier = "riddle"
//Notification Trigger
let date = Date().addingTimeInterval(5)
var dateComponents = DateComponents()
//dateComponents.hour = 9
//dateComponents.minute = 30
//dateComponents.weekday = 4 //Wednesday
let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true)
//Create Request
let uuidString = UUID().uuidString
let request = UNNotificationRequest(identifier: uuidString, content: content, trigger: trigger)
//Register Request
center.add(request) { (error) in
//Check the parameter and handle any errors
}
}
if let value = UDM.shared.defaults.value(forKey: "riddleNotification") as? Bool {
Home.riddleNotification = value
}
if Home.riddleNotification == true {
riddleNotification()
}
else if Home.riddleNotification == false {
print("no riddle notification scheduled")
}
else {
let isRegisteredForRemoteNotifications = UIApplication.shared.isRegisteredForRemoteNotifications
if isRegisteredForRemoteNotifications {
// User is registered for notification
Home.riddleNotification = true
UDM.shared.defaults.setValue(Home.riddleNotification, forKey: "riddleNotification")
}
else {
// Show alert user is not registered for notification
Home.riddleNotification = false
UDM.shared.defaults.setValue(Home.riddleNotification, forKey: "riddleNotification")
}
riddleNotification()
}
}
@IBAction func Riddles(_ sender: Any) {
let vc = SFSafariViewController(url: URL(string: "https://riddles.com")!)
present(vc, animated: true)
}
@IBAction func RiddlesandAnswers(_ sender: Any) {
let vc = SFSafariViewController(url: URL(string: "https://riddlesandanswers.com")!)
present(vc, animated: true)
}
@IBAction func menuTappedHome(_ sender: Any) {
if menuOut == false {
leadingHome.constant = 150
trailingHome.constant = -150
menuOut = true
}
else {
leadingHome.constant = 0
trailingHome.constant = 0
menuOut = false
}
UIView.animate(withDuration: 0.2, delay: 0.0, options: .curveEaseIn, animations: {
self.view.layoutIfNeeded()
}) { (animationComplete) in
print("The animation is complete")
}
}
}
class UDM {
static let shared = UDM()
let defaults = UserDefaults(suiteName: "com.riddlewednesday.saved.data")!
}
class Settings: UIViewController {
@IBOutlet weak var leading_Settings: NSLayoutConstraint!
@IBOutlet weak var trailing_Settings: NSLayoutConstraint!
@IBOutlet var riddleSwitch: UISwitch!
var menuOut = false
override func viewDidLoad() {
super.viewDidLoad()
if Home.riddleNotification == true {
riddleSwitch.setOn(true, animated: true)
}
if Home.riddleNotification == false {
riddleSwitch.setOn(false, animated: true)
}
}
@IBAction func menuTappedSettings(_ sender: Any) {
if menuOut == false {
leading_Settings.constant = 150
trailing_Settings.constant = -150
menuOut = true
}
else {
leading_Settings.constant = 0
trailing_Settings.constant = 0
menuOut = false
}
UIView.animate(withDuration: 0.2, delay: 0.0, options: .curveEaseIn, animations: {
self.view.layoutIfNeeded()
}) { (animationComplete) in
print("The animation is complete")
}
}
@IBAction func riddleSwitchDidChange(_ sender: Any) {
if riddleSwitch.isOn {
Home.riddleNotification = true
UDM.shared.defaults.setValue(Home.riddleNotification, forKey: "riddleNotification")
}
else {
Home.riddleNotification = false
UDM.shared.defaults.setValue(Home.riddleNotification, forKey: "riddleNotification")
}
}
}


I continue in a second answer for authorisation request.
Continuation…


When I initially determine if they allowed notifications something in there isn’t correct. I need code asking if they allowed local notification

To request authorisation, do this:
Code Block
let center = UNUserNotificationCenter.current()
center.delegate = self
center.getNotificationSettings(completionHandler: { (settings) in
if settings.authorizationStatus == .notDetermined {
// Notification permission has not been asked yet, go for it!
// Notification permission was previously denied, go to settings & privacy to re-enable
center.requestAuthorization(options: [.alert, .sound, .badge]) { (granted, error) in
DispatchQueue.main.async {
// Enable or disable features based on authorization.
if !granted {
let alert = UIAlertController(title: NSLocalizedString("Notification ", comment: ""), message: "", preferredStyle: .alert)
alert.message = NSLocalizedString("Notifications disabled: Activate in Settings.", comment: "")
alert.addAction(UIAlertAction(title: NSLocalizedString("ok", comment: ""), style: .cancel) { _ in
// continue your work
})
self.present(alert, animated: true, completion: nil)
}
}
}
} else if settings.authorizationStatus == .denied {
DispatchQueue.main.async {
let alert = UIAlertController(title: NSLocalizedString("Notification ", comment: ""), message: "", preferredStyle: .alert)
// Enable or disable features based on authorization.
alert.message = NSLocalizedString("Notifications disabled: Activate in Settings.", comment: "")
alert.addAction(UIAlertAction(title: NSLocalizedString("ok", comment: ""), style: .cancel) { _ in
// continue your work
})
self.present(alert, animated: true, completion: nil)
}
} else if settings.authorizationStatus == .authorized {
// Notification permission was already granted
}
})
```

Note that date is never used (line 31)
That didn't work to check, nothing happened with the switch.

Here is my current Home.swift code:

Code Block //
import UIKit
import SafariServices
import UserNotifications
class Home: UIViewController, UNUserNotificationCenterDelegate {    
    @IBOutlet weak var leadingHome: NSLayoutConstraint!
    @IBOutlet weak var trailingHome: NSLayoutConstraint!
    
    var menuOut = false
    
    static var riddleNotification = Bool()
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //Ask for Notification Permision
        let center = UNUserNotificationCenter.current()
        center.requestAuthorization(options: [.alert, .sound, .badge]) { (granted, error) in
        }
        
        
        func riddleNotification() {
            
            //Notification Content
            let content = UNMutableNotificationContent()
            content.title = "Check out this weeks riddle!"
            content.body = "This weeks riddle is..."
            content.categoryIdentifier = "riddle"
            
            //Notification Trigger
            let date = Date().addingTimeInterval(5)
            
            var dateComponents = DateComponents()
            //dateComponents.hour = 9
            //dateComponents.minute = 30
            //dateComponents.weekday = 4 //Wednesday
            let trigger = UNCalendarNotificationTrigger(dateMatching: dateComponents, repeats: true)
            
            //Create Request
            
            let uuidString = UUID().uuidString
            let request = UNNotificationRequest(identifier: uuidString, content: content, trigger: trigger)
            
            //Register Request
            center.add(request) { (error) in
                //Check the parameter and handle any errors
            print("riddle notification scheduled")
        }
        }
        
        if (UDM.shared.defaults.object(forKey: "riddleNotification") != nil) {
            center.delegate = self
                    center.getNotificationSettings(completionHandler: { (settings) in
                            if settings.authorizationStatus == .notDetermined {
                                    // Notification permission has not been asked yet, go for it!
                                    // Notification permission was previously denied, go to settings & privacy to re-enable
                                    center.requestAuthorization(options: [.alert, .sound, .badge]) { (granted, error) in
                                            
                                            DispatchQueue.main.async {
                                                    // Enable or disable features based on authorization.
                                                    if !granted {
                                                            let alert = UIAlertController(title: NSLocalizedString("Notification ", comment: ""), message: "", preferredStyle: .alert)
                                                            alert.message = NSLocalizedString("Notifications disabled: Activate in Settings.", comment: "")
                                                            alert.addAction(UIAlertAction(title: NSLocalizedString("ok", comment: ""), style: .cancel) { _ in
                                                                    // continue your work
                                                            })
                                                            
                                                            self.present(alert, animated: true, completion: nil)
                                                    }
                                            }
                                    }
                            } else if settings.authorizationStatus == .denied {
                                    DispatchQueue.main.async {
                                            let alert = UIAlertController(title: NSLocalizedString("Notification ", comment: ""), message: "", preferredStyle: .alert)
                                            // Enable or disable features based on authorization.
                                            alert.message = NSLocalizedString("Notifications disabled: Activate in Settings.", comment: "")
                                            alert.addAction(UIAlertAction(title: NSLocalizedString("ok", comment: ""), style: .cancel) { _ in
                                                    // continue your work
                                                Home.riddleNotification = false
                                                UDM.shared.defaults.setValue(Home.riddleNotification, forKey: "riddleNotification")
                                            })
                                            
                                            self.present(alert, animated: true, completion: nil)
                                    }
                            } else if settings.authorizationStatus == .authorized {
                                    // Notification permission was already granted
                                Home.riddleNotification = true
                                UDM.shared.defaults.setValue(Home.riddleNotification, forKey: "riddleNotification")
                                riddleNotification()
                            }
                    })
        }
        if let value = UDM.shared.defaults.value(forKey: "riddleNotification") as? Bool {
            Home.riddleNotification = value
            }
        if Home.riddleNotification == true {
                 riddleNotification()
                }
        else if Home.riddleNotification == false {
                        print("no riddle notification scheduled")
                }
       }
    
    @IBAction func Riddles(_ sender: Any) {
        let vc = SFSafariViewController(url: URL(string: "https://riddles.com")!)
        
        present(vc, animated: true)
    }
    
    @IBAction func RiddlesandAnswers(_ sender: Any) {
        let vc = SFSafariViewController(url: URL(string: "https://riddlesandanswers.com")!)
        
        present(vc, animated: true)
    }
    
    @IBAction func menuTappedHome(_ sender: Any) {
        
        if menuOut == false {
            leadingHome.constant = 150
            trailingHome.constant = -150
            menuOut = true
        }
        else {
            leadingHome.constant = 0
            trailingHome.constant = 0
            menuOut = false
        }
        UIView.animate(withDuration: 0.2, delay: 0.0, options: .curveEaseIn, animations: {
            self.view.layoutIfNeeded()
        }) { (animationComplete) in
            print("The animation is complete")
        }
    }  
}
class UDM {    
    static let shared = UDM()
    let defaults = UserDefaults(suiteName: "com.riddlewednesday.saved.data")!
}

You reply 2 months later…

Sorry, I totally forgot the context and too long to reassess.

Next time, try to reply more rapidly to suggestions made.

Wish you good luck.
Sorry and thank you
In App Settings
 
 
Q