UserDefaults在viewDidLoad中不生效,iOS登录状态持久化问题
问题分析与解决方案
先聊聊你代码里导致无效果的核心问题:
1. 静态变量的实现逻辑问题
你在User类里定义的isLoggedIn是存储属性,它只会在类第一次初始化时读取一次UserDefaults的值,之后修改这个变量并不会自动同步到UserDefaults;而且后续访问该变量时,也不会重新从UserDefaults获取最新值,相当于这个变量和本地存储完全脱节了。
2. 拼写大小写错误
Swift是严格区分大小写的,你的代码里出现了User.isLoggedin、user.isloggedin这些写法,和你定义的isLoggedIn(注意大写的I和末尾的n)不统一,这会直接导致变量访问失败或判断逻辑失效。
修复方案(完全保留你的变量使用方式,无需大规模修改)
只需要把User类里的存储属性改成计算属性,就能让变量和UserDefaults实时同步,同时统一所有调用处的拼写:
第一步:修正User类的变量实现
class User { static var isLoggedIn: Bool { get { // 每次访问时从UserDefaults读取最新值 UserDefaults.standard.bool(forKey: "islogged") } set { // 每次设置时把新值同步保存到UserDefaults UserDefaults.standard.set(newValue, forKey: "islogged") } } }
第二步:修正所有调用处的拼写
登录按钮Action代码:
ButtonAction: { User.isLoggedIn = true // 统一为正确的变量名 // 执行Segue跳转至首页 }
LoginViewController的ViewDidLoad代码:
override func viewDidLoad() { super.viewDidLoad() if User.isLoggedIn { // 注意大写的U和正确的变量名 // 执行Segue跳转至首页 } else { // 显示提示弹窗 } }
额外优化建议(可选,无需大规模修改)
如果想让APP启动时直接判断登录状态跳转到对应页面(避免先加载登录页再跳转的突兀感),可以在SceneDelegate(iOS13+)的scene(_:willConnectTo:options:)方法里添加判断逻辑:
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { guard let windowScene = (scene as? UIWindowScene) else { return } let window = UIWindow(windowScene: windowScene) self.window = window if User.isLoggedIn { // 初始化首页控制器并设置为根视图 let homeVC = HomeScreenController() window.rootViewController = UINavigationController(rootViewController: homeVC) } else { // 初始化登录控制器并设置为根视图 let loginVC = LoginViewController() window.rootViewController = UINavigationController(rootViewController: loginVC) } window.makeKeyAndVisible() }
这个优化能提升用户体验,完全是可选操作,你可以根据实际项目情况决定是否添加。
内容的提问来源于stack exchange,提问作者Jaseel.Dev
相关产品推荐
相关产品推荐

