首次启动应用程序检测失败,我该怎么办?

Unsuccessful detection of first app launching , how should I do it?

我有一个应用程序和一个演练屏幕,如果用户第一次打开该应用程序,我想显示演练屏幕,但我做错了。我应该将代码放在第一个屏幕内的 AppDelegate 还是 ViewDidLoad 中。 这是我使用的代码:

  super.viewDidLoad()

    if UserDefaults.standard.bool(forKey: "isFirstLaunch") {

        UserDefaults.standard.set(true, forKey: "isFirstLaunch")
        UserDefaults.standard.synchronize()
    }
    let isFirstLaunch = UserDefaults.standard.value(forKey: "isFirstLaunch") as? Bool
    if isFirstLaunch! {

            let mainStoryboard = UIStoryboard(name: "ViewController", bundle: Bundle.main)
            let vc : ViewController = mainStoryboard.instantiateViewController(withIdentifier: "ViewController") as! ViewController
            self.present(vc, animated: true, completion: nil)


    }

以及错误图片:

知道怎么做吗?

您的错误与展开可选值有关。您应该做的是检查用户默认值中是否有值。

if let isFirstLaunch = UserDefaults.standard.bool(forKey: "isFirstLaunch") {
    //execute code for when it isn't the first launch
} else {
    //set value of isFirstLaunch for the first time
}

如果 isFirstLaunch 为 nil,则表示这是第一次启动。

你有几个问题:

  1. 您不必要地将密钥设置为 true 她已经是 true
  2. 您不必要地调用 synchronize
  3. 您正在使用 value(forKey:) 而不是 bool(forKey:)
  4. (这就是你崩溃的原因)你没有打开你得到的值,这意味着你的应用程序在值为 nil 时崩溃

你只需要这样的东西:

let defaults = UserDefaults()
if !defaults.bool(forKey:"walkthroughShown") {
   defaults.set(true, forKey:"walkthroughShown")
   // Display your Walkthrough
}

viewDidLoad 不能用作此代码的位置,您最好在应用程序委托中使用此代码来呈现演练 您的初始视图控制器

(Apple) 推荐的方法是 注册 默认值(如 class UserDefaults 暗示).

尽快 - 例如在 applicationWillFinishLaunching - 插入

let defaultValues = ["isFirstLaunch" : true]
UserDefaults.standard.register(defaults: defaultValues)

最早的时刻是应用程序委托中的init方法

override init()
{
    let defaultValues = ["isFirstLaunch" : true]
    UserDefaults.standard.register(defaults: defaultValues)
    super.init()
}

然后简单地写

func viewDidLoad()
    super.viewDidLoad()
    let defaults = UserDefaults.standard
    if defaults.bool(forKey: "isFirstLaunch") {
        defaults.set(false, forKey: "isFirstLaunch")
        let mainStoryboard = UIStoryboard(name: "ViewController", bundle: Bundle.main)
        let vc : ViewController = mainStoryboard.instantiateViewController(withIdentifier: "ViewController") as! ViewController
        self.present(vc, animated: true, completion: nil)
    }
}

在第一次更改之前,默认值一直被考虑。

您应该先解包值:

if let isFirstStart = UserDefaults.standard.value(forKey: "isFirstLaunch") as? Bool {
   // the isFirstStart value exists, you can check the value
} else {
   // the isFirstStart value does not exist
}

我认为 isFirstStart 是一个糟糕的措辞约定,因为它不可能在第一次为真(因为之前没有设置过)。你应该使用例如hasStarted,它表示如果该值不存在,它之前没有启动过,如果存在并且为真,它已经启动了。

希望对您有所帮助,欢迎随时提问。