You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift登录页面“记住用户”功能无法跳转主界面(window为nil)

登录后自动跳转主页面失败(window为nil问题解决)

问题背景

需要实现登录后“记住用户”并自动跳转到主ViewController,但功能未生效。验证代码逻辑是通的(修改withIdentifier字符串会立刻报错),但添加打印语句后始终输出“window is nil”。已在AppDelegate中声明var window: UIWindow?,代码如下:

let user : String? = UserDefaults.standard.string(forKey: "username")
    
if user != nil {
        
    let board : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
        
    let myTag = board.instantiateViewController(withIdentifier: "myTags") as! mainBeaconList
        
        
    print("mainBeaconList: \(myTag)")

    if let window = window {
        print("window: \(window)")
        window.rootViewController = myTag
    } else {
        print("window is nil")
    }
}

核心原因与解决方案

window为nil的问题分两种场景,对应不同解决方式:

场景1:iOS12及以下版本

AppDelegate中仅声明了window变量,但未完成初始化。需在application(_:didFinishLaunchingWithOptions:)方法中先初始化window,再执行跳转逻辑:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // 初始化window并设置为可见
    window = UIWindow(frame: UIScreen.main.bounds)
    window?.makeKeyAndVisible()
    
    // 自动跳转逻辑
    if let _ = UserDefaults.standard.string(forKey: "username") {
        let board = UIStoryboard(name: "Main", bundle: nil)
        let mainVC = board.instantiateViewController(withIdentifier: "myTags") as! mainBeaconList
        window?.rootViewController = mainVC
    } else {
        // 未登录时显示登录页(替换为你的登录页Storyboard ID)
        let loginVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "LoginVC")
        window?.rootViewController = loginVC
    }
    return true
}

场景2:iOS13及以上版本

iOS13后系统窗口管理转移至SceneDelegate,AppDelegate中的window不再生效。需将跳转逻辑移至SceneDelegate的scene(_:willConnectTo:options:)方法:

func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    guard let windowScene = (scene as? UIWindowScene) else { return }
    
    // 初始化window并设置为可见
    let window = UIWindow(windowScene: windowScene)
    self.window = window
    window.makeKeyAndVisible()
    
    // 自动跳转逻辑
    if let _ = UserDefaults.standard.string(forKey: "username") {
        let board = UIStoryboard(name: "Main", bundle: nil)
        let mainVC = board.instantiateViewController(withIdentifier: "myTags") as! mainBeaconList
        window.rootViewController = mainVC
    } else {
        // 未登录时显示登录页(替换为你的登录页Storyboard ID)
        let loginVC = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "LoginVC")
        window.rootViewController = loginVC
    }
}

额外注意事项

  • 确保Storyboard中ViewController的Storyboard ID与代码中的"myTags"完全一致,大小写敏感。
  • 遵循Swift命名规范,类名首字母大写(如mainBeaconList改为MainBeaconList),避免类型转换隐患。
  • 建议使用if let user = UserDefaults.standard.string(forKey: "username")这种可选绑定方式,替代if user != nil,代码更安全简洁。

内容的提问来源于stack exchange,提问作者Serdar Percin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 21:46:05