Search code examples
swiftuilabelnsuserdefaultsappdelegate

Store label value (date) in UserDefaults on exiting the app


My goal is to store the date displayed on timeLabel when the user exits the app. When the app is run again, label should display the same time as when user exited the app.

I know I have to somehow save the timeLabel to the user defaults the first time the user leaves the app. I don't know if I have to do anything with app delegate either.

import UIKit

class ViewController: UIViewController {
var currentDateTime = Date()
var timeLabel = UILabel()
let defaults = UserDefaults.standard


override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view.

     let dateFormatter = DateFormatter()
    dateFormatter.dateStyle = .medium

    view.addSubview(timeLabel)
    timeLabel.translatesAutoresizingMaskIntoConstraints = false
    timeLabel.backgroundColor = .systemRed
     timeLabel.text = "\(dateFormatter.string(from: currentDateTime))"

    NSLayoutConstraint.activate([

        timeLabel.topAnchor.constraint(equalTo: view.topAnchor, constant: 10),
        timeLabel.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 10),
        timeLabel.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.4, constant: 49),
        timeLabel.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.4, constant: 49),



    ])

    defaults.set(timeLabel.text, forKey: "label")
}


}

Solution

  • The problem there is that you are not loading your string from UserDefaults. So create a method in your view controller to be executed when your app will enter foreground, try to read the string and update your label with it.

    @objc func willEnterForeground(_ notification: Notification) {
        if let string = defaults.string(forKey: "label") {
            timeLabel.text = string
        }
    }
    

    To save the date when the user leaves your app or when it goes to the background you can add an observer for iOS12 or earlier use UIApplication.willResignActiveNotification, for iOS13 or later use UIScene.willDeactivateNotification. Then add a selector to handle the deactivation.

    Do the same for UIScene.willEnterForegroundNotification and UIApplication.willEnterForegroundNotification

    Add those observers to your view controller inside viewDidLoad method:

    if #available(iOS 13.0, *) {
        NotificationCenter.default.addObserver(self, selector: #selector(willResignActive), name: UIScene.willDeactivateNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(willEnterForeground), name: UIScene.willEnterForegroundNotification, object: nil)
    } else {
        NotificationCenter.default.addObserver(self, selector: #selector(willResignActive), name: UIApplication.willResignActiveNotification, object: nil)
        NotificationCenter.default.addObserver(self, selector: #selector(willEnterForeground), name: UIApplication.willEnterForegroundNotification, object: nil)
    }
    

    Create your method to save the string to the UserDefaults. It is not clear if your intent is to save it every time the user leaves your application or if you want to save it only the first time. To save it every time your app goes to the background:

    @objc func willResignActive(_ notification: Notification) {
        let dateFormatter = DateFormatter()
        dateFormatter.dateStyle = .medium
        dateFormatter.timeStyle = .medium
        let string = dateFormatter.string(from: Date())
        defaults.set(string, forKey: "label")
    }