Search code examples
swiftuserdefaults

How can I make it so that I can only type once per day?


I want to save and manage a bool value in userDefaults so that I cannot input the exercise time again until the date is changed after the first exercise time is entered.

 func nextDate(){
        var compoenet = Calendar.current.dateComponents([.year, .month, .day], from: Date())
        compoenet.timeZone = TimeZone(abbreviation: "UTC")
        
        let dateWithoutTime = Calendar.current.date(from: compoenet)!
        
        let date = Date()
    
        inputDateAvailable.value = UserDefaults.standard.bool(forKey: "inputDateAvailable")
        print("userDefaults = \(UserDefaults.standard.bool(forKey: "inputDateAvailable"))")
        print("date \(date)")
        print(dateWithoutTime)
        
        if date == dateWithoutTime {
            inputDateAvailable.value = true
            print("present 됨")
        } else {
            inputDateAvailable.value = false
            print("present 안됨")
        }
    }
    
    func saveInputDateAvailable() {
        UserDefaults.standard.set(false, forKey: "inputDateAvailable")
    }

it's my ViewModel code.

and


    @objc func profileBtnDidTap(_ sender: UIButton) {
        guard viewModel.inputDateAvailable.value else {
            viewModel.pushProfileGraphVC()
            return
        }
        viewModel.profileBtnDidTap()
        viewModel.nextDate()
    }

    override func configureVC() {
        viewModel.saveInputDateAvailable()
}

it's my ViewController code

I've been thinking too much. It's too hard for me to create the logic I want. please help me


Solution

  • With the sparse information you provided it seems way easier to store the date whenever the pushProfileGraphVC func is executed and check it before execution.

    Change this:

    func saveInputDateAvailable() {
        UserDefaults.standard.set(Calendar.current.startOfDay(for: Date()), forKey: "inputDate")
    }
    

    and add this

    func isInputDateValid() -> Bool{
        UserDefaults.standard.object(forKey: "inputDate") as? Date != Calendar.current.startOfDay(for: Date())
    }
    

    function to your viewmodel.

    change your profileBtnDidTap function to:

    @objc func profileBtnDidTap(_ sender: UIButton) {
        guard viewModel.isInputDateValid() else {
            viewModel.pushProfileGraphVC()
            return
        }
        viewModel.profileBtnDidTap()
    }
    

    You can remove nextDate.

    Be aware! saveInputDateAvailable should only be executed when whatever Viewcontroller you are pushing with pushProfileGraphVC is shown. So the function should either be called from within pushProfileGraphVC function or

    override func configureVC() {
            viewModel.saveInputDateAvailable()
    

    should reside in the pushed Viewcontroller.