首次应用程序启动未能成功检测,我该怎么做?

4

我有一个应用程序和一个引导屏幕,如果用户第一次打开应用程序,我想显示引导屏幕,但我做错了。我应该将代码放在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)


    }

并且有一个错误的图片:

在此输入图片描述

有什么想法如何解决?


我在GitHub上找到了一份类似的代码。 这是链接:https://github.com/karanthakakr04/Walkthrough-Demo.git 希望它能满足你的需求。此外,如果有人需要,这里还有一个参考教程:https://youtu.be/tNCsQe5vfRk - Karan Thakkar
4个回答

2
您有一些问题:
  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 不适合作为这段代码的位置,你最好在你的应用程序委托中使用这段代码来呈现Walkthrough 或者 你的初始视图控制器。


谢谢,显示演示文稿的代码应该是什么? - Ivan

1

(苹果)推荐的方法是将默认值注册为类UserDefaults所暗示的那样,register

尽快在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)
    }
}

默认值在第一次更改之前被视为有效。

我应该在AppDelegate中编写以下代码吗?let defaultValues = ["isFirstLaunch" : true] UserDefaults.standard.register(defaults: defaultValues)然后在viewDidLoad中编写剩下的代码,还是将所有代码都放在一个ViewController中? - Ivan
是的,在AppDelegate中,无论如何您都必须确保在视图控制器中的viewDidLoad方法之前执行注册默认值的行。 - vadian
当我第一次启动应用程序时,我收到了一个错误信号SIGBART。我将其放置在applicationWillFinishLaunching中,但它仍然无法正常工作。有任何想法吗? :( - Ivan
我更新了答案,建议将代码放在AppDelegate的init方法中。如果错误仍然发生,则与用户默认设置无关。 - vadian
再次出现相同的错误。 可以把代码发给你看看吗,因为你更专业。 - Ivan

0

你的错误与解包一个可选值有关。你应该检查用户默认设置中是否有任何值。

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,那就意味着这是第一次启动。

UserDefaults bool(forKey:) 不返回可选类型。这段代码无法编译。 - rmaddy

0

你应该先解包这个值:

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,它表示如果值不存在,则尚未启动,如果存在且为true,则已经启动。
希望这可以帮助到你,如有任何问题请随时问。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接