Swift 在SQLite上插入新行时返回Nil

Swift 在SQLite上插入新行时返回Nil,swift,xcode,sqlite,null,Swift,Xcode,Sqlite,Null,我一直在使用SQLite作为我正在开发的这个应用程序的本地存储,但是,当我尝试运行我的数据库并在SQLite表中插入新行时,它给了我一个零返回并使应用程序崩溃。插入新行的方式是通过在viewController类中创建的函数,但是,当我在Create table函数中使用固定值运行相同的代码时,它会工作,我不明白为什么?(我在另一个类中使用addIngerdient) 致命错误:隐式展开可选值时意外发现nil:file/Users/ian/Desktop/IA/IA/ViewController

我一直在使用SQLite作为我正在开发的这个应用程序的本地存储,但是,当我尝试运行我的数据库并在SQLite表中插入新行时,它给了我一个零返回并使应用程序崩溃。插入新行的方式是通过在viewController类中创建的函数,但是,当我在Create table函数中使用固定值运行相同的代码时,它会工作,我不明白为什么?(我在另一个类中使用addIngerdient)

致命错误:隐式展开可选值时意外发现nil:file/Users/ian/Desktop/IA/IA/ViewController.swift,第89行 2020-10-20 16:07:18.209118+0800 IA[3723:173664]致命错误:在隐式展开可选值时意外发现零:file/Users/ian/Desktop/IA/IA/ViewController.swift,第89行 (lldb)

//
//ViewController.swift
//IA
//
//伊恩·东于20年8月19日创作。
//版权所有©2020伊恩·东。版权所有。
//
导入UIKit
导入SQLite
类ViewController:UIViewController{
公共var数据库:连接!
让InTable=表格(“ingerdients”)
设iID=表达式(“ingerdientID”)
让iName=表达式(“ingerdientName”)
设iAmount=表达式(“ingerdientAmount”)
重写func viewDidLoad(){
super.viewDidLoad()
做{
让documentDirectory=try FileManager.default.url(对于:.documentDirectory,在:.userDomainMask中,适用于:nil,创建:true)
让fileUrl=documentDirectory.appendingPathComponent(“ingerdients”).appendingPathExtension(“sqlite3”)
let database=尝试连接(fileUrl.path)
self.database=数据库
}
抓住{
打印(“错误”)
}
}
@iAction func加载列表(\发送方:任意){
}
@iAction func createTable()
{
打印(“正在等待创建表”)
让createTable=self.ingTable.create{(表)在
表.列(self.iID,primaryKey:true)
table.column(self.iName,unique:true)
表.列(自身iAmount)
}
做{
尝试self.database.run(createTable)
打印(“已创建表”)
}
抓住{
打印(错误)
}
做{
let ingerdients=尝试self.database.prepare(self.ingTable)
对于ingerdients中的ingerdients{
打印(“ingerdientName:\(ingerdientName[self.iName]),ingerdientAmount:\(ingerdientName[self.iAmount]))
}
}
抓住
{
打印(错误)
}

让insertIngerdient=self.ingTable.insert(self.iName稍微偏离主题,您不应该将数据库代码放在视图控制器中,而应该放在单独的结构或类中。从代码中调用createTable的位置是什么?您是说我应该为我的数据库创建一个新的swift文件吗?是的,最好将具有不同职责的代码分为不同的类型(结构或类).但是那次零事故呢?原因是什么?
//
//  ViewController.swift
//  IA
//
//  Created by Ian Dong on 8/19/20.
//  Copyright © 2020 Ian Dong. All rights reserved.
//

import UIKit
import SQLite

class ViewController: UIViewController {

   public var database: Connection!
    
    let ingTable = Table("ingerdients")
    let iID = Expression<Int>("ingerdientID")
    let iName = Expression<String>("ingerdientName")
    let iAmount = Expression<Double>("ingerdientAmount")
    
    
    
    override func viewDidLoad() {
        super.viewDidLoad()
    do{
        let documentDirectory = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
        let fileUrl = documentDirectory.appendingPathComponent("ingerdients").appendingPathExtension("sqlite3")
        let database = try Connection(fileUrl.path)
        self.database = database
       }
       catch {
       print("error")
       }
        
    }
    
    @IBAction func LoadList(_ sender: Any) {
        
    }
    
    
   @IBAction func createTable()
    {
        print("waiting to create table")
        let createTable = self.ingTable.create { (table) in
            table.column(self.iID, primaryKey: true)
            table.column(self.iName, unique: true)
            table.column(self.iAmount)
        }
        do{
            try self.database.run(createTable)
            print("Table has been created")
        }
        catch{
            print(error)
        }
        do{
            let ingerdients = try self.database.prepare(self.ingTable)
            for ingerdient in ingerdients{
                print(" ingerdientName: \(ingerdient[self.iName]), ingerdientAmount: \(ingerdient[self.iAmount])")
        }
        }
        catch
        {
            print(error)
        }
        
        let insertIngerdient = self.ingTable.insert(self.iName <- "asd", self.iAmount <- 2.3) //the same code as the addIngerident function
               
               do{
                try self.database.run(insertIngerdient)
                   print("Ingerdient ","asd",  " Inserted")
               }
               catch{
                   print(error)
                   print("unable to insertIngerdient")
               }
    }
    
   
      func addIngerdient( sName: String, ingAmount: Double)
       {
           let newIngerident = Ingerdient(Name: sName, Amount: ingAmount)
           
           let insertIngerdient = self.ingTable.insert(self.iName <- sName, self.iAmount <- ingAmount)
           
           do{
            try self.database.run(insertIngerdient) // Thread 1: Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
               print("Ingerdient ", sName,  " Inserted")
           }
           catch{
               print(error)
               print("unable to insertIngerdient")
           }
       }
        
   func listIngerdient()
    {
        do{
            let ingerdients = try self.database.prepare(self.ingTable)
            for ingerdient in ingerdients{
                print("ingeridentID: \(ingerdient[self.iID]), ingerdientName: \(ingerdient[self.iName]), ingerdientAmount: \(ingerdient[self.iAmount])")
        }
        }
        catch
        {
            print(error)
        }
    }
 
    
    
    
    func updataIngerdientList() -> Array<String>
    {
        var IngList: [String] = []
     
        do{
            var k: Int = 0
          let ingerdients = try self.database.prepare(self.ingTable)
            for ingerdient in ingerdients
            {
                var A: String = String(ingerdient[self.iAmount])
                IngList[k] = ingerdient[self.iName] + " --- " + A
            }
            
        }
        catch
        {
            print(error)
        }
        return IngList
    }
 
    
    func editIngerdient( ingName: String, newAmount: Double){
        
        let ingerdient = self.ingTable.filter(self.iName == ingName)
        let updateIngerdient = ingerdient.update(self.iAmount <- newAmount)
        do {
            try self.database.run(updateIngerdient)
        }
        catch {
            print(error)
        }
    }
    
    
    let mTable = Table("mealPlan")
       let mName = Expression<String>("mealName")
       let mIng = Expression<Array<IngerdientCost>>("ingerdientList")
       let mTest = Expression<IngerdientCost>("test")
    
}