Swift - 应用程序在设置 UserDefaults 后崩溃

Swift - app crashes after setting UserDefaults

我正在尝试在我的应用程序中实现 "always logged in" 功能。问题是,如果我重新启动我的应用程序,它就会崩溃。这就是我所做的:

设置用户默认值:

@objc func loginButtonTapped(_ sender: Any) {

    let email = self.emailTextField.text!.trimmingCharacters(in: .whitespacesAndNewlines)
    let password = self.passwordTextField.text!.trimmingCharacters(in: .whitespacesAndNewlines)
    // start button animation
    loginButton.startAnimation()

    let qualityOfServiceClass = DispatchQoS.QoSClass.background
    let backgorundQueue = DispatchQueue.global(qos: qualityOfServiceClass)
    backgorundQueue.async {
        // check if account details correct
        Auth.auth().signIn(withEmail: email, password: password) { (result, error) in

            if error != nil {
                DispatchQueue.main.async {
                    // error -> stop animation
                    self.loginButton.stopAnimation(animationStyle: .shake, revertAfterDelay: 0) {
                        self.errorLabel.text = error!.localizedDescription
                        self.errorLabel.alpha = 1
                    }
                }
            }else {
                // correct acount details -> login
                DispatchQueue.main.async {
                    UserDefaults.standard.set(true, forKey: "isLoggedIn")
                    UserDefaults.standard.synchronize()
                    // transition to home ViewController
                    self.transitionToHome()
                }
            }
        }
    }
}

正在检查用户默认值:

class MainNavigationControllerViewController: UINavigationController {

override func viewDidLoad() {
    super.viewDidLoad()

    if isLoggedIn() {
        let homeController = MainViewController()
        viewControllers = [homeController]
    }
}

fileprivate func isLoggedIn() -> Bool {
    return UserDefaults.standard.bool(forKey: "isLoggedIn")
}

}

用户通过Firebase登录,所有数据都存储在Cloud Firestore中。

错误

cell.customWishlistTapCallback = {

            let heroID = "wishlistImageIDX\(indexPath)"
            cell.theView.heroID = heroID

            let addButtonHeroID = "addWishButtonID"
            self.addButton.heroID = addButtonHeroID

            // track selected index
            self.currentWishListIDX = indexPath.item

            let vc = self.storyboard?.instantiateViewController(withIdentifier: "WishlistVC") as? WishlistViewController

            vc?.wishList = self.dataSourceArray[self.currentWishListIDX]
            // pass drop down options
            vc?.theDropDownOptions = self.dropDownButton.dropView.dropDownOptions
            vc?.theDropDownImageOptions = self.dropDownButton.dropView.dropDownListImages
            // pass current wishlist index
            vc?.currentWishListIDX = self.currentWishListIDX
            // pass the data array
            vc?.dataSourceArray = self.dataSourceArray
            // set Hero ID for transition
            vc?.wishlistImage.heroID = heroID
            vc?.addWishButton.heroID = addButtonHeroID
            // allow MainVC to recieve updated datasource array
            vc?.dismissWishDelegate = self

            vc?.theTableView.tableView.reloadData()
            self.present(vc!, animated: true, completion: nil)

        }

Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)

行:

let vc = self.storyboard?.instantiateViewController(withIdentifier: "WishlistVC") as! WishlistViewController

我想这并不像我想象的那么容易。有谁知道应用程序崩溃的原因以及我如何解决这个问题? :)

您正在使用简单的初始化程序 (MainViewController()) 创建 MainViewController 实例,而不是从故事板实例化它。因此,任何 @IBOutlet 属性都将是 nil,因为它是分配这些对象实例并将它们分配给属性的故事板进程。

您需要向主视图控制器场景添加一个标识符(如果它还没有)并使用它来实例化视图控制器实例。例如。假设场景标识符是 "MainScene" 你会得到类似的东西:

override func viewDidLoad() {
    super.viewDidLoad()

    if isLoggedIn() {
        let homeController = UIStoryboard(name: "Main", bundle: nil).instantiateViewControllerWithIdentifier("MainScene") 
        viewControllers = [homeController]
    }
}

您更新后的问题中的崩溃表明标识符为 WishlistVC 的场景没有将其 class 设置为 WishlistViewController 或者未找到,因此强制沮丧崩溃。