Joe
Joe

Reputation: 250

Why all IBOutlet(s) found nil when viewdidload is called in App Delegate?

My Xcode debugger reports, every other values include alive (bool value) is set, except all the IBOutlets found nil (myLine, etc.). By the way, everything works when I delete all the code in App Delegate, but I need this view to update frequently, so implement it in applicationWillEnterForeground is necessary. And another thing worth pointing out, in the configure view 1 and 2, I set each outlet's value. And I make app delegate call viewdidload method before that, so all the outlets should hooked up with code already, so those outlets shouldn't be nil.

An error message in the debugger -- fatal error: unexpectedly found nil while unwrapping an Optional value

import UIKit

class ViewController: UIViewController {

    var alive : Bool = true
    var aliveDefault = NSUserDefaults.standardUserDefaults()


    //IBOulet Connections

    @IBOutlet weak var myLine: UILabel!

    @IBAction func buttontapped(sender: AnyObject) {
        alive = false
        NSUserDefaults.standardUserDefaults().setObject(alive, forKey: "alive")
    }

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

        loadView()
    }
    func loadView(){
         alive = aliveDefault.boolForKey("alive")
         if alive = true {
            configureView()
          }else{
            configureView2()
        }
    }

    func configureView(){
        myLine.text = "Random text"
    }

    func configureView2(){
        myLine.text = "Random text 2"
    }
}

App Delegate

func applicationWillEnterForeground(application: UIApplication) {
        // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
    ViewController().viewDidLoad()
    ViewController().configureView()
}

Upvotes: 3

Views: 1966

Answers (2)

rajeeva9
rajeeva9

Reputation: 139

Do ViewController.loadViewIfNeeded() before assigning values to IBOutlets

Upvotes: 0

Paulw11
Paulw11

Reputation: 114975

Since you are creating two new instances of ViewController in applicationWillEnterForeground using the default initialiser rather than from the storyboard, none of the IBOutlets will be set. You need to update the current instance of the view controller that is on screen.

Rather than doing this from the appDelegate it is probably easier to have your view controller subscribe to the UIApplicationWillEnterForegroundNotification NSNotification and handle the refresh locally. This way you don't need to closely couple your app delegate and your view controller and you don't need to worry if the view controller isn't currently on screen:

class ViewController: UIViewController {

    ...

    override func viewWillAppear(animated: Bool) {
        super.viewWillAppear(animated)
        NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ViewController.loadView), name: UIApplicationWillEnterForegroundNotification, object: nil)
    }

    override func viewWillDisappear(animated: Bool) {
        super.viewWillDisappear(animated)
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }

Upvotes: 3

Related Questions