简体   繁体   English

重新启动应用程序后,Swift UserDefaults 不会持续存在

[英]Swift UserDefaults not persisting after relaunching app

I am having a problem with my UserDefault settings not persisting when my app launches.当我的应用程序启动时,我的 UserDefault 设置没有持续存在的问题。 I have read other posts on this matter and most are marked solved after various tips.我已经阅读了有关此问题的其他帖子,并且大多数都在各种提示后标记为已解决。 I have implemented all of the suggested tips (that I am aware of) and I still have this problem.我已经实施了所有建议的技巧(我知道),但我仍然遇到这个问题。

I have created the simplest sample app.我创建了最简单的示例应用程序。 The app has has a button that toggles between Login/Logout depending on the current state of a UserDefault setting called "isLoggedIn."该应用程序有一个按钮,可以根据名为“isLoggedIn”的 UserDefault 设置的当前状态在登录/注销之间切换。

Here's the code...这是代码...

import UIKit

class LoginViewController: UIViewController {

    @IBOutlet weak var loginButton: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()        
    }

    override func viewDidAppear(_ animated: Bool) {
        refreshButton()
    }

    @IBAction func loginButtonPressed(_ sender: UIButton) {
        let isLoggedIn = UserDefaults.standard.bool(forKey: "isLoggedIn")
    
        UserDefaults.standard.set(!isLoggedIn, forKey: "isLoggedIn")
    
        refreshButton()
    }

    func refreshButton() {
        let isLoggedIn = UserDefaults.standard.bool(forKey: "isLoggedIn")
            
        loginButton.setTitle(isLoggedIn ? "Logout" : "Login", for: .normal)
    }

}

When the button is clicked, the UserDefault setting is updated and the button is refreshed to display Login or Logout based on the new setting.单击按钮时,会更新 UserDefault 设置并刷新按钮以根据新设置显示登录或注销。 If I run the app in the simulator I can see the button toggle which tells me that the UserDefault setting is being stored properly.如果我在模拟器中运行应用程序,我可以看到按钮切换,它告诉我 UserDefault 设置已正确存储。

The problem occurs when I relaunch the app.当我重新启动应用程序时会出现问题。 The button is refreshed to show the last state of the UserDefault setting when the app was closed.当应用程序关闭时,该按钮会刷新以显示 UserDefault 设置的最后状态。 But it doesn't always properly reflect the previous state.但它并不总是正确地反映以前的状态。 Occasionally it does but I more often it does not.偶尔会,但我更多时候不会。 I cannot see any pattern here either.我在这里也看不到任何模式。

I have tried...我努力了...

  • Using the set method instead of the setValue method使用set方法而不是setValue方法
  • Calling the synchronize method after applying the update (I'm aware that Apple says this is no longer required or suggested)应用更新后调用synchronize方法(我知道 Apple 表示不再需要或建议这样做)

I just cannot pinpoint what I am overlooking.我只是无法确定我忽略了什么。 Does anyone have any ideas about what I am doing wrong?有人对我做错了什么有任何想法吗? Please let me know if I can provide any additional code that might help.如果我可以提供任何可能有帮助的其他代码,请告诉我。

Thanks, Joel谢谢,乔尔

UPDATE更新

I decided to track the actual changes to the setting in the plist file itself.我决定跟踪 plist 文件本身中设置的实际更改。 Upon inspection, I noticed that the setting was taking several seconds to physically update in the file.经过检查,我注意到该设置需要几秒钟才能在文件中进行物理更新。 Therefore, if I wait for several seconds before closing my app then the setting will save and it will display properly when I launch again.因此,如果我在关闭我的应用程序之前等待几秒钟,那么设置将保存并且当我再次启动时它会正确显示。 So new question is...所以新的问题是...

  • Why does it take so long for my setting to save?为什么我的设置需要这么长时间才能保存?
  • and can I ensure that the app does not close before the setting is properly saved?我可以确保在正确保存设置之前应用程序不会关闭吗?

It's funny because I thought that was the purpose of the synchronize method that Apple say not to use anymore.这很有趣,因为我认为这是 Apple 说不再使​​用的synchronize方法的目的。

Thanks again!再次感谢!

import UIKit

class LoginViewController: UIViewController {
    var isLogin = false
    @IBOutlet weak var loginButton: UIButton!

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        refreshButton()
    }


    @IBAction func loginButtonPressed(_ sender: UIButton) {
        isLogin.toggle()
        UserDefaults.standard.set(isLogin, forKey: "isLoggedIn")
        refreshButton()
    }

    func refreshButton() {
        isLogin = UserDefaults.standard.bool(forKey: "isLoggedIn")
            
        loginButton.setTitle(isLogin ? "Logout" : "Login", for: .normal)
    }

}

There is an explanation for your questions, it is because of the way how UserDefault system works.您的问题有一个解释,这是因为UserDefault系统的工作方式。 Usually, it takes time to save your data.通常,保存数据需要时间。 You might be losing data during your application development.您可能会在应用程序开发过程中丢失数据。 For example, if you are developing an application with swift , when you changed some codes in your project and launch your app then click the stop button in Xcode , you will probably lose some of the data, because at that moment, some of the data still in the memory waiting for being saved.例如,如果您正在使用swift开发应用程序,当您更改项目中的一些代码并启动您的应用程序然后单击Xcode中的停止按钮时,您可能会丢失一些数据,因为那一刻,一些数据还在记忆中等待被保存。

But do not worry, it will be saved eventually when your application is published to the users.但是不用担心,当您的应用程序发布给用户时,它最终会被保存。

By the way, I have tested my project, I install my iOS app on my iPhone without using XCode , and it saves all of the data either I close my app on the tasks list(swipe out) or click the home button and open the app again, the data still there.顺便说一句,我已经测试了我的项目,我在我的 iPhone 上安装了我的 iOS 应用程序而不使用XCode ,它保存了所有数据,或者我在任务列表中关闭我的应用程序(滑出)或单击主页按钮并打开再次应用,数据还在。

Here, hope this article will clear your confusion: Why Do You Lose Data Stored in User Defaults在这里,希望这篇文章能消除您的困惑: 为什么您会丢失存储在用户默认值中的数据

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM