0

I am trying to have my application open a different view controller based upon whether an array is empty in the user's NSUserDefaults. Essentially, if the user has previously saved data in the app, the app will open up to where they can select the data. Otherwise, the app will open to a welcome screen.

However, when the array is empty, I see the background color that I set for the welcome screen, but not the text or button that I laid out in the storyboard. When the array is not empty and the data page should open, my app crashes with a SIGABRT error. I checked all of the outlets for the view controller in question and nothing seems to be disconnected. Additionally, when I comment out the code in the app delegate and set the data view controller as my initial starting view, the app runs fine.

The full error is "Thread 1: signal SIGABRT" and it is tagged in the class AppDelegate line.

The code I used in the App Delegate is below:

class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        var accounts = loadAccounts()!

        if accounts.isEmpty {
            let welcomeController = WelcomeViewController()
            self.window!.rootViewController = welcomeController
        } else {
            let tableController = AccountTableViewController()
            self.window!.rootViewController = tableController
        }

        return true
    }

    func loadAccounts() -> [Account]? {
        return NSKeyedUnarchiver.unarchiveObject(withFile: Account.ArchiveURL.path) as? [Account]
    }
  • Why do you force unwrap the result of calling `loadAccounts`? If it returns an optional, don't force unwrap it. – rmaddy Jan 24 '19 at 04:39
  • Which line exactly is causing the crash? What is the complete error message? Please put these detail in your question (do not post them in a comment). – rmaddy Jan 24 '19 at 04:40
  • Sorry about that, I've just added in the full error line in the question. It's the same error that I have received in the past when there was an outlet not connected, but I haven't found that to be the case when troubleshooting this error. – Henry Benson Jan 24 '19 at 04:51
  • You need to set an exception breakpoint so you can find out the exact line causing the error. And you need to get the full error message. There should be a lot more than just "SIGABRT". – rmaddy Jan 24 '19 at 04:53
  • You can’t simply instantiate a view controller like this as it doesn’t create the views or controls. A view controller can be used on multiple different storyboard views so you need to associate the view controller with an actual view. What you need is storyboard.instantiateViewControllerWithIdentifier(). See https://stackoverflow.com/a/26757245/1852207 – Dale Jan 24 '19 at 05:18
  • Thanks, Dale! That thread that you shared helped me figure this out! – Henry Benson Jan 24 '19 at 21:45

1 Answers1

0

Maybe the UIWindow is not set properly.

let bounds = UIScreen.main.bounds
self.window = UIWindow(frame: bounds)
self.window?.rootViewController = `your view controller`
self.window?.makeKeyAndVisible()

What else can go wrong?

var accounts = loadAccounts()!

This line is the culprit for you. Precisely this symbol ! is I guess. You are trying to fetch data from a database or a filesystem and expect it will always be there.

Think about it, it can't be true all the time.

 # check if account array is not empty; I would have returned nil if it would be empty and so we can avoid that extra check here.
 if let accounts = loadAccounts(), !accounts.isEmpty {

     let tableController = AccountTableViewController()
     self.window!.rootViewController = tableController

     return true
 }

 let welcomeController = WelcomeViewController()
 self.window!.rootViewController = welcomeController

Also, if you can provide more info about the error message from your debug console. Then I would be able to help in a better way.

Rahul
  • 2,056
  • 1
  • 21
  • 37
  • Thanks for the suggestions! I've just updated the question with the full error, which is tagged in the class AppDelegate line. I don't believe there should be any problems with force unwrapping loadAccounts because there is content in there with the simulator that I am using. In any case, I've made it optional, but the error still occurred. The error also occurred when I tried fixing the UIWindow. – Henry Benson Jan 24 '19 at 04:55
  • I think there might be an issue with the `ViewControllers`. Check if you can just open that two viewController with dummy data. – Rahul Jan 24 '19 at 05:03
  • I guess they meant you haven't initialized the window property of your AppDelegate before trying to unwrap it. Unless you did that somewhere else in the code. – f3dm76 Jan 24 '19 at 05:22