SQLite/Swift 5 Fatal Error

Hello:


The code below worked fine until I syddenly started getting this error and the app crash when I try to save or retrieve a record:


2019-05-09 14:18:05.809199-0400 No Regrets[18485:4452452] [MC] Reading from private effective user settings.

Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value

2019-05-09 14:18:23.716878-0400 No Regrets[18485:4452452] Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value


I need help to identify what could be causing the crash.


Swift 5 CODE:

import UIKit

import SQLite3



class ViewController: UIViewController, UITextFieldDelegate {


@IBOutlet weak var noRegretsLabel: UILabel!


@IBOutlet weak var usernameTextField: UITextField!


@IBOutlet weak var decisionTextField: UITextField!


var databasePath = String()

var database: FMDatabase?

var username: UITextField!

var decision: UITextField!


override func viewDidLoad(){

super.viewDidLoad()

usernameTextField.delegate = self

decisionTextField.delegate = self

initDB()

}


override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

usernameTextField.resignFirstResponder()

decisionTextField.resignFirstResponder()

}

func initDB() {

let filemgr = FileManager.default

let dirPaths = filemgr.urls(for: .documentDirectory,

in: .userDomainMask)

databasePath = dirPaths[0].appendingPathComponent("decisions").path

if !filemgr.fileExists(atPath: databasePath) {

let decisionDB = FMDatabase(path: databasePath)

if (decisionDB.open()) {

let sql_stmt = "create table if not exists decisions (id integer primary key autoincrement,username text,decision text)"

if !(decisionDB.executeStatements(sql_stmt)) {

print("Error: \(decisionDB.lastErrorMessage())")

}

decisionDB.close()

} else {

print("Error: \(decisionDB.lastErrorMessage())")

}

}

}



@IBAction func saveDecision(_ sender: Any) {


let decisionDB = FMDatabase(path: databasePath)

if (decisionDB.open()) {

let insertSQL = "insert into decisions(username, decision) VALUES ('\(username.text ?? "")', '\(decision.text ?? "")')"

do {

try decisionDB.executeUpdate(insertSQL,values: nil)

} catch {

username.text = "Failed to add contact"

print("Error: \(error.localizedDescription)")

}

username.text = "Decision Added"

username.text = ""

decision.text = ""


}else{

print ("Error: \(decisionDB.lastErrorMessage())")

}

}


@IBAction func findDecision(_ sender: Any) {


let decisionDB = FMDatabase(path: databasePath)

if (decisionDB.open()) {

let querySQL = "select username, decision from decisions where username = '\(username.text!)'"

do {

let results:FMResultSet? = try decisionDB.executeQuery(querySQL,

values:nil)

if results?.next() == true {

username.text = results?.string(forColumn: "username")

decision.text = results?.string(forColumn: "decision")

username.text = "Record Found"

}else{

username.text = "Record not Found"

username.text = ""

decision.text = ""

}

}catch{

print("Error: \(error.localizedDescription)")

}

decisionDB.close()

}else{

print("Error: \(decisionDB.lastErrorMessage())")

}

}

}

Answered by OOPer in 359924022

The line that is highlighted when i click the SAVE button is: line 69 (your formatting)


Then, your `username` and/or `decision` are nil (maybe both) there.


When I click the FIND button: line 84 (your formatting) the line that is highlighted is:


It is indicating your `username` (maybe) or `username.text` is nil.


In your code, you declare two properties `var username: UITextField!` and `var decision: UITextField!`, but you never assign something to these two properties. So, anywhere in your code using `username` or `decision`, your app may crash as expected.


The two lines should be as follows, I think:

let insertSQL = "INSERT INTO DECISIONS(username, decision) VALUES ('\(usernameTextField.text ?? "")', '\(decisionTextField.text ?? "")')"


let querySQL = "SELECT username, decision FROM decisions WHERE username = '\(usernameTextField.text ?? "")'"


You may need to modify so many other parts, as you are using `username` and `decision` so often.

Why have you declared such unsafe properties?

You should first format the code you post, like this:


import UIKit
import SQLite3

class ViewController: UIViewController, UITextFieldDelegate {
 
    @IBOutlet weak var noRegretsLabel: UILabel!
 
    @IBOutlet weak var usernameTextField: UITextField!
 
    @IBOutlet weak var decisionTextField: UITextField!
 
    var databasePath = String()
    var database: FMDatabase?
    var username: UITextField!
    var decision: UITextField!
 
    override func viewDidLoad(){
        super.viewDidLoad()
     
        usernameTextField.delegate = self
        decisionTextField.delegate = self
     
            initDB()
    }
 
   override func touchesBegan(_ touches: Set, with event: UIEvent?) {
        usernameTextField.resignFirstResponder()
        decisionTextField.resignFirstResponder()
    }
    func initDB() {
        let filemgr = FileManager.default
        let dirPaths = filemgr.urls(for: .documentDirectory,
                                    in: .userDomainMask)
     
        databasePath = dirPaths[0].appendingPathComponent("decisions").path
     
        if !filemgr.fileExists(atPath: databasePath) {
         
            let decisionDB = FMDatabase(path: databasePath)
         
            if (decisionDB.open()) {
            
                let sql_stmt = "create table if not exists decisions (id integer primary key autoincrement,username text,decision text)"
                if !(decisionDB.executeStatements(sql_stmt)) {
                    print("Error: \(decisionDB.lastErrorMessage())")
                }
                decisionDB.close()
            } else {
                print("Error: \(decisionDB.lastErrorMessage())")
            }
         
        }
     
    }
 
 
    @IBAction func saveDecision(_ sender: Any) {
 
    let decisionDB = FMDatabase(path: databasePath)
        if (decisionDB.open()) {
        
            let insertSQL = "insert into decisions(username, decision) VALUES ('\(username.text ?? "")', '\(decision.text ?? "")')"
         
            do {
                try decisionDB.executeUpdate(insertSQL,values: nil)
            } catch {
                username.text = "Failed to add contact"
                print("Error: \(error.localizedDescription)")
             
            }
            username.text = "Decision Added"
            username.text = ""
            decision.text = ""

        } else {
            print ("Error: \(decisionDB.lastErrorMessage())")
        }
    }
 
    @IBAction func findDecision(_ sender: Any) {
 
        let decisionDB = FMDatabase(path: databasePath)
        if (decisionDB.open()) {
            let querySQL = "select username, decision from decisions where username = '\(username.text!)'"
         
            do {
                let results:FMResultSet? = try decisionDB.executeQuery(querySQL,
                                                                      values:nil)
                if results?.next() == true {
                    username.text = results?.string(forColumn: "username")
                   decision.text = results?.string(forColumn: "decision")
                    username.text = "Record Found"
                }else{
                   username.text = "Record not Found"
                   username.text = ""
                   decision.text = ""
                }
            }catch{
                print("Error: \(error.localizedDescription)")
            }
            decisionDB.close()
        }else{
            print("Error: \(decisionDB.lastErrorMessage())")
         
        }
    }
}

Then tell which line you crash. Until then, difficult to say, but


Usual suspects :

- You may have an outlet disconnected or ill connected (if you changed the name for instance)

Hello Claude31:


The line that is highlighted when i click the SAVE button is: line 69 (your formatting)


let insertSQL = "INSERT INTO DECISIONS(username, decision) VALUES ('\(username.text ?? "")', '\(decision.text ?? "")')"


and the error is:



2019-05-10 11:16:44.192064-0400 No Regrets[1716:748391] Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value

warning: could not execute support code to read Objective-C class data in the process. This may reduce the quality of type information available.

(lldb)


AND


When I click the FIND button: line 84 (your formatting) the line that is highlighted is:


let querySQL = "SELECT username, decision FROM decisions WHERE username = '\(username.text!)'"


and the error message is:



Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value

2019-05-10 11:22:11.743805-0400 No Regrets[1720:749596] Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value

(lldb)

Accepted Answer

The line that is highlighted when i click the SAVE button is: line 69 (your formatting)


Then, your `username` and/or `decision` are nil (maybe both) there.


When I click the FIND button: line 84 (your formatting) the line that is highlighted is:


It is indicating your `username` (maybe) or `username.text` is nil.


In your code, you declare two properties `var username: UITextField!` and `var decision: UITextField!`, but you never assign something to these two properties. So, anywhere in your code using `username` or `decision`, your app may crash as expected.


The two lines should be as follows, I think:

let insertSQL = "INSERT INTO DECISIONS(username, decision) VALUES ('\(usernameTextField.text ?? "")', '\(decisionTextField.text ?? "")')"


let querySQL = "SELECT username, decision FROM decisions WHERE username = '\(usernameTextField.text ?? "")'"


You may need to modify so many other parts, as you are using `username` and `decision` so often.

Why have you declared such unsafe properties?

Hello OOPer:


Your solution was exactly the answer to my problem. I am just learning SWIFT and something as simple as an incorrect use of the defined variable just slips by me. Thanks.

SQLite/Swift 5 Fatal Error
 
 
Q