-2

I begin swift and i'm making an app ( a little game). The buttons of levels 2,... are not enabled because the user dont yet win the level 1 when the user install the application. then I want these buttons enabled everytime the user won the level. I wrote this in a file:

class levelList: UIViewController {
    @IBOutlet var blvl1: UIButton!
    @IBOutlet var blvl2: UIButton!
    @IBOutlet var blvl3: UIButton!

    var lvlWon1: Bool = false {
        didSet {
            blvl2?.enabled = lvlWon1

        }
    }

    var lvlWon2: Bool = false {
        didSet {
            blvl3?.enabled = lvlWon2
        }
    }
    let lvl1Default = NSUserDefaults.standardUserDefaults()
    let lvl2Default = NSUserDefaults.standardUserDefaults()


    override func viewDidLoad() {

        if (lvl1Default.objectForKey("lvlWon1") != nil){
            lvl1Default.setBool(true, forKey: "lvlWon1")
            lvlWon1 = lvl1Default.valueForKey("lvlWon1") as! Bool!
        }
        else{
            lvl1Default.setBool(false, forKey: "lvlWon1")
            lvlWon1 = lvl1Default.valueForKey("lvlWon1") as! Bool!
        }

        //
        if (lvl2Default.objectForKey("lvlWon2") != nil){
            lvl2Default.setBool(true, forKey: "lvlWon2")
            lvlWon2 = lvl2Default.valueForKey("lvlWon2") as! Bool!
        }
        else{
            lvl2Default.setBool(false, forKey: "lvlWon2")
            lvlWon2 = lvl2Default.valueForKey("lvlWon2") as! Bool!
        }

    }
}

and this in an other file:

class lvl1: UIViewController {

var levelList = levelList()
@IBOutlet var bNext: UIButton!
@IBAction func nextlvl(sender: UIButton) {
    levelList.lvlWon1 = true
    levelList.lvlWon1 = levelList.lvl1Default.valueForKey("lvlWon1") as! Bool!
    let lvl1Default = NSUserDefaults.standardUserDefaults()
    lvl1Default.setValue(listeNiveaux.lvlWon1, forKey:"lvlWon1")
    lvl1Default.synchronize()
}

//my problem is that all work finely when I wrote:

var lvlWon1: Bool = false {
    didSet {
        blvl2?.enabled = lvlWon1

    }
}

so when i won the lvl 1, the level2 button is enabled, but when i add

var lvlWon2: Bool = false {
    didSet {
        blvl3?.enabled = lvlWon2
    }
}

when I win the level1, the blvl2 and the blvl3 are enabled, I don't know why

I think it's because i save the data of all blvl but i'm not sure. thanks in advance and really sorry for my english, it's not my first language.

Asdrubal
  • 2,421
  • 4
  • 29
  • 37

2 Answers2

1

The problem is because you are calling NSUserDefaults.standardUserDefaults() twice, in order to fix it you could:

  1. Create a new variable named defaults and store the user defaults instance, so that this let lvl1Default = NSUserDefaults.standardUserDefaults() let lvl2Default = NSUserDefaults.standardUserDefaults() becomes let defaults = NSUserDefaults.standardUserDefaults()
  2. Use that new variable replacing the previous lvl1Default and lvl2Default on viewDidLoad (and do not forget to call super)

    override func viewDidLoad() {
    super.viewDidLoad()
    
    if (defaults.objectForKey("lvlWon1") != nil){
        defaults.setBool(true, forKey: "lvlWon1")
        lvlWon1 = defaults.valueForKey("lvlWon1") as! Bool
    }
    else{
        defaults.setBool(false, forKey: "lvlWon1")
        lvlWon1 = defaults.valueForKey("lvlWon1") as! Bool
    }
    
    //
    if (defaults.objectForKey("lvlWon2") != nil){
        defaults.setBool(true, forKey: "lvlWon2")
        lvlWon2 = defaults.valueForKey("lvlWon2") as! Bool
    }
    else{
        defaults.setBool(false, forKey: "lvlWon2")
        lvlWon2 = defaults.valueForKey("lvlWon2") as! Bool
    }        
    }
    

Edit after 2016-08-10 comment: On my first attempt to provide an answer to your problem, I tried to isolate the problem and I succesfully managed to recreate it without considering the code on the lvl1 class. Since this did not solved your issue, I made a second attempt taking the nextlvl function in consideration.

On this function, there is another NSUserDefaults.standardUserDefaults() call. The first thing I would do is to make the 'defaults' constant (explained previously) as a global variable so that you can access it everywhere. (in case you need more info about this, you could check this answer) Another thing I noticed is the call to synchronize() which is deprecated.

So, after moving the defaults constant to somewhere global, I think what you meant to do on the nextlvl function should be:

@IBAction func nextlvl(sender: UIButton) {
    lvlWon1 = true
    defaults.setBool(true, forKey: "lvlWon1");
}

Edit 2: As a side note: When you are casting lvlWon2 = defaults.valueForKey("lvlWon2") as! Bool! you do not need to place ! in the type, as in as! Bool! you just need as! Bool

Bool is a boolean type that cannot be null whereas Bool! means a boolean type that is implicitly unwrapped and Bool? means a boolean type needs to be unwrapped.

If you wish to read more about wrappers, check The Swift Programming Language reference

You can also use defaults.boolForKey("lvlWon2") which gives you the result as a Bool type and avoid the casting.

Community
  • 1
  • 1
  • i replaced all lvl1Deafault and lvl2Default by defaults .. but when win the level 1, blvl1,blvl2 and blvl3 are enabled. I dont want blvl3 is enabled because "i dont won yet the level2". – Matt Jacquet Aug 09 '16 at 09:34
  • @Matt Jacquet This steps solved the problem on a test I did, however I placed the `lvlWon1 = true` logic on the `levelList` view controller. If this did not fix the issue, maybe the problem it is on the `nextlvl` function but I do not quite understand it – Rodrigo Ruiz Murguía Aug 09 '16 at 14:55
  • i really don't understand. i replaced all `lvlDefault` by `defaults` in levelList file and lvl1 file but the blvl3 still enabled when i finish lvl 1 . i gave you all my code about these functions .. – Matt Jacquet Aug 10 '16 at 09:58
  • i just understad, you said "i placed `lvlWon1 = true` logic on the levelList viewController" you mean `blvl1` enabled? – Matt Jacquet Aug 10 '16 at 10:10
  • before seeing your answer, i noticed all problems come from the code of viewDidLoad. i think it's because i wrote `}else { defaults.setBool(false, forKey: "lvlWon1") lvlWon1 = defaults.valueForKey("lvlWon1") as! Bool }` like when `defaults == nil` , it equal to false.. does it change your answer? – Matt Jacquet Aug 11 '16 at 20:45
0

I finally found the solution :

 import UIKit

class ViewController: UIViewController {

 var defaults = NSUserDefaults.standardUserDefaults()

 @IBOutlet weak var startSecondLevelButton: UIButton!

 override func viewDidLoad() {
super.viewDidLoad()

self.checkLevelsStatuses()
    }

 func checkLevelsStatuses() {

startSecondLevelButton.enabled = false

if let lvlWon1 = defaults.objectForKey("lvlWon1") as? Bool {
    // if true - level finished
    if (lvlWon1) {
        startSecondLevelButton.enabled = true
    }
}else {
    defaults.setBool(false, forKey: "lvlWon1")
}

if let lvlWon2 = defaults.objectForKey("lvlWon2") as? Bool {

} else {
    defaults.setBool(false, forKey: "lvlWon2")
}

}

that was because the viewDidLoad was wrong.