I'm have a hard time creating a user setting options. I would like the user to customize the frequency of the timer to receive the local notifications. I'm using a switch on the SystemSettingsVC to for the user to select and set the user default and I'm using the user default setting in my MainVC for the TimerInterval. My app runs but the time doesnt change. I know that the switch is working because I'm also testing the background color change.
Here is my code for my SystemSettingsVC: ...
import UIKit
import SwiftUI
import CoreData
class SettingsViewController: UIViewController {
@IBOutlet weak var timeSelection: UISegmentedControl!
let userDefaults = UserDefaults.standard
let TIME_KEY = "TIME_KEY"
let ONE_HOUR_KEY = 60.0
let THREE_HOUR_KEY = 120.0
let SIX_HOUR_KEY = 300.0
override func viewDidLoad() {
super.viewDidLoad()
updateTime()
}
func updateTime() {
let time = userDefaults.object(forKey: "TIME_KEY")
if(time as? Double == ONE_HOUR_KEY) {
timeSelection.selectedSegmentIndex = 0
let userDefaults = UserDefaults.standard
userDefaults.set(60.0, forKey: "TIME_KEY")
view.backgroundColor = UIColor.white
save()
}
else if(time as? Double == THREE_HOUR_KEY) {
timeSelection.selectedSegmentIndex = 1
let userDefaults = UserDefaults.standard
userDefaults.set(120.0, forKey: "TIME_KEY")
view.backgroundColor = UIColor.gray
save()
}
else if(time as? Double == SIX_HOUR_KEY) {
timeSelection.selectedSegmentIndex = 2
let userDefaults = UserDefaults.standard
userDefaults.set(300.0, forKey: "TIME_KEY")
view.backgroundColor = UIColor.darkGray
save()
}
}
func save() {
if let savedData = try? NSKeyedArchiver.archivedData(withRootObject: clock, requiringSecureCoding: false){
let defaults = UserDefaults.standard
defaults.set(savedData, forKey: "TIME_KEY")
}
}
@IBAction func selectTimeOfQuotes(_ sender: Any) {
switch timeSelection.selectedSegmentIndex
{
case 0:
userDefaults.set(60.0, forKey: "TIME_KEY")
save()
case 1:
userDefaults.set(120.0, forKey: "TIME_KEY")
save()
case 2:
userDefaults.set(300.0, forKey: "TIME_KEY")
save()
default:
userDefaults.set(60.0, forKey: "TIME_KEY")
save()
}
updateTime()
}
}
...
Here is the code for my view controller to where I call the user defaults, I placed let userDefaults = UserDefaults.standard in my ViewDidLoad : '''Code''' ```
func configureAlerts() {
let center = UNUserNotificationCenter.current()
center.removeAllDeliveredNotifications()
center.removeAllPendingNotificationRequests()
let listQuotes = quotes
let i = 1
let content = UNMutableNotificationContent()
content.title = “Inspire”
content.body = listQuotes[i].shareMessage
content.sound = UNNotificationSound.default
let alertDate = Date().byAdding(days: i)
var alertComponents = Calendar.current.dateComponents([.day, .month, .year], from: alertDate)
alertComponents.hour = 8
let userDefaults = UserDefaults.standard
typealias NSTimeInterval = Double
let thisTime:TimeInterval = userDefaults.double(forKey: "TIME_KEY")
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: thisTime, repeats: true)
let uuidString = UUID().uuidString
let request = UNNotificationRequest(identifier: uuidString, content: content, trigger: trigger)
center.add(request) { error in
if let error = error {
print(error.localizedDescription)
}
}
You are not showing how your Models are connected so we can't tell where the miscommunication is happening or maybe that is the issue. They are not connected.
But at a simple glance you are not rescheduling the notifications.
selectTimeOfQuotes,saveorupdateTimedo not callconfigureAlerts.Something to note you have a lot of repeating code and hardcoded values that could be the source of the confusion.
BTW 120 is 2 hours not 3 idk if that is on purpose but it highlights my next point.
When you change a value you only want to do it in 1 place; if possible; so centralizing the models will help you avoid having to change things in multiple places.
For the options for your picker an
enumcan hold everything.Then since you have at least 2 unrelated classes that use the value store in user defaults you can centralize that work too
Then your
SettingsViewControllerwill look like thisAs the last line of code shows once all the work is done you should reschedule the quotes.
I created a mini-
QuoteManagersince you do not show this connection. This manager can be used by any View Controller to get the quotes and maybe even reschedule when the quotes change by calling the provided method.The
QuoteManagercalls theNotificationManager. I created a small version below.It might seem like a lot but if you focus on the
SettingsViewControlleryou will see how much simpler the whole thing becomes.All this is working code. Just copy and paste into a
.swiftfile.You might have to change the
UISegmentedControlsince I created it programmatically but if you put theSettingsViewControllerin a blank storyboard it should work as is.