Swift 在SQLite上插入新行时返回Nil
我一直在使用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)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
//
//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")
}