1
votes

I am very new to programming, and I have been looking online for a few days now trying to address this issue that I have been have with my Swift programming. I am new to all of this; and, I have tried my earnest to try and find a solution on my own. But, after this frustrating time, I though that it would be okay to ask the experts.

The code that I am trying to use is this:

import UIKit
class ViewController: UIViewController {

    var myTime: AnyObject = NSUserDefaults() //creates a var called myTime that can be used to save the time parameter.
    var timer = NSTimer() // creates a variable used by the timer loop.

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        myTime = NSUserDefaults.standardUserDefaults().objectForKey("two")! //sets timer value to last saved value

        if (myTime as NSNumber == 0){ //if the initial value doesnt exhist the if statement creates one.
            NSUserDefaults.standardUserDefaults().setInteger(0, forKey: "two") //sets timer to zero and saves parameter
        }

        timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("action"), userInfo: nil, repeats: true) // Creates a timer at 1 second time interval which then performs function called 'action' and will continue until boolean is set to false or NSTimer is invalidated.
    }

    func action(){

        myTime = Int(myTime as NSNumber) + 1 // increases myTime by 1
        println(myTime) //println(time) // prints myTime

        NSUserDefaults.standardUserDefaults().setInteger(myTime as Int, forKey: "two") // saving variable two with value of 2
        NSUserDefaults.standardUserDefaults().synchronize() // Added synchronize as suggested by LAMMERT WESTERHOFF
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

The error message that I am receiving is this:

fatal error: unexpectedly found nil while unwrapping an Optional value (lldb)

Saying:

Thread 1: EXC_BAD_INSTRUCTION (code=EXC_1386_INVOP, subcode=0x0)

I would sincerely appreciate it if someone could tell me what I am doing wrong and how to solve my problem.

1
You don't say which line is giving you the error but consider that the first time you run the code there will be no entries in the user defaults. That makes me think the problem is .objectForKey("two")!. You can't guarantee that there will be such an object.Phillip Mills

1 Answers

2
votes

The error occurs here

myTime = NSUserDefaults.standardUserDefaults().objectForKey("two")!

this is because you are trying to assign optional value, which can not be nil, to non optional variable.

to resolve this issue you need to set object for key "two" before you will fetch this object or make myTime variable optional

also to check the value you should check it for nil before converting it to NSNumber

this code should work fine

*import UIKit
class ViewController: UIViewController {

//here I added ? which means optional value
    var myTime: AnyObject? = NSUserDefaults() //creates a var called myTime that can be used to save the time parameter.
    var timer = NSTimer() // creates a variable used by the timer loop.

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

// here I removed ! because value for key "two" may not been set so it is optional value
        myTime = NSUserDefaults.standardUserDefaults().objectForKey("two") //sets timer value to last saved value

//here we check myTime object for nil before converting to NSInteger and checking for 0
        if ( myTime == nil || myTime as NSNumber == 0){ //if the initial value doesnt exhist the if statement creates one.
            NSUserDefaults.standardUserDefaults().setInteger(0, forKey: "two") //sets timer to zero and saves parameter
        }

        timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("action"), userInfo: nil, repeats: true) // Creates a timer at 1 second time interval which then performs function called 'action' and will continue until boolean is set to false or NSTimer is invalidated.
    }

    func action(){

        myTime = Int(myTime as NSNumber) + 1 // increases myTime by 1
        println(myTime) //println(time) // prints myTime

        NSUserDefaults.standardUserDefaults().setInteger(myTime as Int, forKey: "two") // saving variable two with value of 2
        NSUserDefaults.standardUserDefaults().synchronize() // Added synchronize as suggested by LAMMERT WESTERHOFF
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}*