Tarvo Mäesepp Tarvo Mäesepp - 24 days ago 7
iOS Question

Check if user has opened every viewcontroller

I would like to know, is it possible to check if user has opened every

viewcontroller
that application has?

I would like to do it because I give user badges and it is the one I would like to give.

I assume I have to store something into
userDefaults
and somehow gather the info and then do what I want to do, am I right? If I am right then should I do some global variable and add count every time user opens new
viewcontroller
?

Any info is appreciated.

Answer

Make an option set to represent every viewController. In each viewControllers ViewDidAppear, read and update a field from Userdefaults that stores the option set of displayed viewControllers then write it back to Userdefaults.

    struct UserDefaultsKey {
        static let displayedViewControllers = "displayedViewControllers"
    }

    struct DisplayedViewControllers: OptionSet {
        let rawValue: Int

        static let vc1 = DisplayedViewControllers(rawValue: 1 << 0)
        static let vc2 = DisplayedViewControllers(rawValue: 1 << 1)
        static let vc3 = DisplayedViewControllers(rawValue: 1 << 2)
        static let vc4 = DisplayedViewControllers(rawValue: 1 << 3)
        static let all = [vc1, vc2, vc3, vc4]
    }

    class vc1: UIViewController {
        override func viewDidAppear(_ animated: Bool) {
            super.viewDidAppear(true)
            var displayedViewControllers = DisplayedViewControllers(rawValue: UserDefaults.standard.integer(forKey: UserDefaultsKey.displayedViewControllers))
            displayedViewControllers.insert(.vc1)
            UserDefaults.standard.set(displayedViewControllers.rawValue, forKey: UserDefaultsKey.displayedViewControllers)
        }
    }

    func haveAllViewControllersBeenDisplayed() -> Bool {
        let displayedViewControllers = DisplayedViewControllers(rawValue: UserDefaults.standard.integer(forKey: UserDefaultsKey.displayedViewControllers))
        for controller in DisplayedViewControllers.all {
            if displayedViewControllers.contains(controller) == false {
                return false
            }
        }
        return true
    }