简体   繁体   中英

Swift4 : FMDBdatabase - Unexpectedly found nil while unwrapping an Optional value

Update:

In the end, I go to the local SQLite database and replace the NULL value to "unkown". This works!

I am using FMDatabaseQueue to search an existing sqlite database in iOS.

//Data model
import Foundation
import UIKit
class scoreModel: NSObject {
    var lessonName:String = String()
    var lessonCode:String = String()
    var creditPoint:Double = Double()
    var totalStudentNumber:Int = Int()
    var teacherName:String = String()
    var semesterName:String = String()
    var scoreValue:String = String()
    var studentCount:Int = Int()
}

Unfortunately, there are some "" string in my database. Like:

teacherName "" 

scoreValue ""

Xcode中错误数据库的图像

While searching, Xcode alerted that

"Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value" in line "teacherName". 

错误图片

I don't need these "" results necessarily as they are not important. How can I fix it?

func queryDB(sql: String) -> NSMutableArray {

    openDB ();
    let resultArray = NSMutableArray()

    SQLiteManager.shareInstance.dbQueue?.inDatabase { (db) in
        let dbResult: FMResultSet! = db.executeQuery(sql, withArgumentsIn:[])

        if (dbResult != nil)
        {
            while dbResult.next() {
                let model:scoreModel = scoreModel()
                model.lessonName = String(dbResult.string(forColumn: "lessonName")!)
                model.lessonCode = String(dbResult.string(forColumn: "lessonCode")!)
                model.creditPoint = Double(dbResult.double(forColumn: "creditPoint"))
                model.semesterName = String(dbResult.string(forColumn: "semesterName")!)
                model.teacherName = String(dbResult.string(forColumn: "teacherName")!)
                model.totalStudentNumber = Int(dbResult.int(forColumn: "totalStudentNumber"))
                model.scoreValue = String(dbResult.string(forColumn: "scoreValue")!)
                model.studentCount = Int(dbResult.int(forColumn: "studentCount"))
                resultArray.add(model)
            }
        }
    }
    return resultArray
}

Thank you!

The problem is that dbResult.string(forColumn: "teacherName") is returning an optional with a nil value, so maybe this object had a nil value when you saved it. It doesn't really matter, what's important is how you want to treat objects that don't have all the fields that you're expecting. The question you need to ask yourself is "how should I handle the case where the thing in the database doesn't have a teacher name?" Here are two ideas:

In order to be considered "valid," everything in the database needs to have all the properties I'm expecting, otherwise I ignore it. That would look like this:

    while dbResult.next() {
        if let lessonName = String(dbResult.string(forColumn: "lessonName")),
        let lessonCode = String.dbResult.string(forColumn: "lessonCode")),
        let creditPoint = Double(dbResult.double(forColumn: "creditPoint")),
        let semesterName = String(dbResult.string(forColumn: "semesterName")),
        let teacherName = String(dbResult.string(forColumn: "teacherName")),
        let totalStudentNumber = Int(dbResult.int(forColumn: "totalStudentNumber")),
        let scoreValue = String(dbResult.string(forColumn: "scoreValue")),
        let studentCount = Int(dbResult.int(forColumn: "studentCount")) {
            let model = scoreModel()
            model.lessonName = lessonName
            ...     // set lessonCode, etc
            resultArray.add(model)
        }
    }

Another choice is to provide default values using optional coalescing or similar.

while dbResult.next() {
    let lessonName = String(dbResult.string(forColumn: "lessonName")) ?? ""
    let lessonCode = String.dbResult.string(forColumn: "lessonCode")) ?? ""
    let creditPoint = Double(dbResult.double(forColumn: "creditPoint")) ?? ""
    let semesterName = String(dbResult.string(forColumn: "semesterName")) ?? ""
    let teacherName = String(dbResult.string(forColumn: "teacherName")) ?? ""
    let totalStudentNumber = Int(dbResult.int(forColumn: "totalStudentNumber")) ?? 0
    let scoreValue = String(dbResult.string(forColumn: "scoreValue")) ?? ""
    let studentCount = Int(dbResult.int(forColumn: "studentCount")) ?? 0
    let model = scoreModel()
    model.lessonName = lessonName
    ...     // set lessonCode, etc
    resultArray.add(model)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM