3

I am developing a walkthrough screen which should appear only the first time when the user opens the app. So far I created the walkthrough page and PageViewController. See the picture: enter image description here

I read lots of similar questions here and I understood that I have to use

  UserDefaults()

inside the AppDelegate, but I didn't understand how to use the class and storyboard names inside the code. Basically, when the app is opened for the first time, the PageViewController should appear on the screen and when the user clicks on the start button, which is on the WalkThroughScreen it will dismiss the tutorial page and the app will start.

I have tried this code:

if let isFirstStart = UserDefaults.standard.value(forKey: "isFirstLaunch") as? Bool {
  if defaults.bool(forKey: "isFirstLaunch") {
    defaults.set(false, forKey: "isFirstLaunch")
    let mainStoryboard = UIStoryboard(name: "WalkThroughScreen", bundle: Bundle.main)
    let vc : WalkThroughScreen = mainStoryboard.instantiateViewController(withIdentifier: "PageViewController") as! WalkThroughScreen
    self.present(vc, animated: true, completion: nil)
     }

I am pretty sure that it is a complete mess, because I didn't understand it very good and I haven't used the TutorialPage, so I will be very thankful if someone leave me hints or example how to do it correctly

Dakata
  • 1,227
  • 2
  • 14
  • 33

2 Answers2

3

Yes you are right, you have to use userDefaults to achieve this. And you have to do it inside appDelegate() Roel Koops answer should do it but you can try it like this also:

  let launchedBefore = UserDefaults.standard.bool(forKey: "launchedBefore")
    if launchedBefore  {
        print("This is not first launch.")
    } else {
        print("This is first launch.")
        UserDefaults.standard.set(true, forKey: "launchedBefore")
        UserDefaults.standard.synchronize()
        let mainStoryboard = UIStoryboard(name: "Main", bundle: Bundle.main)
        let vc : WalkThroughScreen = mainStoryboard.instantiateViewController(withIdentifier: "WalkThroughScreen") as! WalkThroughScreen
        self.present(vc, animated: true, completion: nil)

    }

And make sure to declare: let userDefaults = UserDefaults.standard and use it inside didFinishLaunchingWithOptions.

There are even more solutions so I give you one more:

    let userDefaults = UserDefaults.standard

    if !userDefaults.bool(forKey: "launchedBefore") {
        let mainStoryboard = UIStoryboard(name: "Main", bundle: Bundle.main)
        let vc : WelcomeViewController = mainStoryboard.instantiateViewController(withIdentifier: "WalkThroughScreen") as! WelcomeViewController
        self.window?.makeKeyAndVisible()
        self.window?.rootViewController?.present(vc, animated: false, completion: nil)
        userDefaults.set(true, forKey: "launchedBefore")
        userDefaults.synchronize()

    }

You can even declare all the storyboard thing in one line:

self.window?.rootViewController = self.storyboard?.instantiateViewController(withIdentifier: "WalkThroughScreen")

But this assumes that you declare 2 variables:

var window: UIWindow?
var storyboard: UIStoryboard?

If it didn't work just tell me, I am gonna try to help.

Tarvo Mäesepp
  • 4,477
  • 3
  • 44
  • 92
  • 1
    if this code is placed in appDelegate() as Tarvo Mäesepp is suggesting, then it needs a little bit modification: self.window?.makeKeyAndVisible() self.window?.rootViewController?.present(vc, animated: false, completion: nil) – Roel Koops Nov 01 '16 at 23:12
  • Hey I can't make it working,because I am mixing the vc name and the identifier name. May I send you the app to take a quick look? – Dakata Nov 02 '16 at 22:03
  • I used the same identifiers you gave us. But yes you can send it. – Tarvo Mäesepp Nov 02 '16 at 22:53
  • You can download it from here: http://www.filedropper.com/uipageviewcontrollerexample-master2 – Dakata Nov 02 '16 at 23:37
  • Thank you very much man! It is a sample so that I get the basics and the try to do it by my own. Please share it with me again, so that I can start it on my mac in stead of replacing only the code :) – Dakata Nov 02 '16 at 23:38
  • I have to say that your code is total mess but here you go: https://drive.google.com/file/d/0B587oI34VXz3Z1BBNXFWNEFUTkE/view?usp=sharing – Tarvo Mäesepp Nov 02 '16 at 23:48
  • Thanks man, I download it and tested, but I do not see the Walkthrough screen. When I start the app, I am directly opening the initial view controller. Then I deleted the app to simulate the first Launch and again I see only the initial view. Have you tested it ? – Dakata Nov 03 '16 at 09:13
  • You have to delete you lr app because otherwise it doesn't understand taht it is first launch... and the key is false. I yested and it worked – Tarvo Mäesepp Nov 03 '16 at 11:10
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/127273/discussion-between-dakata-and-tarvo-maesepp). – Dakata Nov 03 '16 at 12:10
2

The code in your if-block is never executed if the key "isFirstLaunch" doesn't exist.

Try this:

    if let isFirstStart = UserDefaults.standard.value(forKey: "isFirstLaunch") as? Bool {
        print("this is not the first launch")
    } else {
        print("this is the first launch")
        UserDefaults.standard.set(false, forKey: "isFirstLaunch")
        UserDefaults.standard.synchronize()

        let mainStoryboard = UIStoryboard(name: "Main", bundle: Bundle.main)
        let vc : WalkThroughScreen = mainStoryboard.instantiateViewController(withIdentifier: "WalkThroughScreen") as! WalkThroughScreen
        self.present(vc, animated: true, completion: nil)
    }
Roel Koops
  • 840
  • 2
  • 16
  • 28
  • Would you please check are the names of the storyboards and the classes are properly used? – Dakata Nov 01 '16 at 22:31
  • See my updated answer. The name of the main storyboard is "Main" by default in the templates. if you didn't change that, above code should by right. – Roel Koops Nov 01 '16 at 22:42
  • I get an error in the last line: there is no member of type "present" – Dakata Nov 02 '16 at 22:05
  • Are you using this code in your AppDelegate? Then you need to present like this: self.window?.makeKeyAndVisible() self.window?.rootViewController?.present(vc, animated: false, completion: nil) – Roel Koops Nov 03 '16 at 06:34
  • where exactly should this code be kept in Appdelegate class? – TheSwiftGuy77 Jul 25 '18 at 09:54