• 汇入 SQLite3 的 C API,让我们可以直接操作 SQLite 资料库
  • import SQLite3

  • 在class ViewController放入
  • var db :SQLiteConnect? // 定义一个可选型别的资料库连线物件,型别为自订的 SQLiteConnect

    // 使用闭包来建立一个 dbURL,该 URL 指向应用程式文件目录下的 db.sqlite 资料库档案。
    // 使用 FileManager 找出文件目录,如果失败就呼叫 fatalError 终止程式。
    var dbURL: URL = {
    do {
    return try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true).appendingPathComponent("db.sqlite")
    } catch {
    fatalError("Error getting db URL from document directory.")
    }
    }()

  • 在override func viewDidLoad()放入
  • // 连接资料库,建立 SQLite 资料库连线,传入前面建立的资料库路径
    db = SQLiteConnect(path: dbURL.path)

  • 在func updateRecordsList()放入
  • // 如果资料库连线成功,则清空先前的资料集合,并初始化本月总金额为 0。
    // 如果资料库连线成功,则清空先前的资料集合,并初始化本月总金额为 0。
    if let mydb = db {
    days = []
    myRecords = [:]
    eachDayAmount = [:]
    var total = 0.0

    // 呼叫自订的 fetch 方法从资料库中捞取符合当前年月的记录,并以建立时间及 id 进行排序
    let statement = mydb.fetch("records", cond: "yearMonth == \'\\(yearMonth)\'", order: "createTime desc, id desc")

    // 透过迴圈读取每笔资料,分别取出 id、title、amount 以及 createDate(建立日期)
    // 使用 SQLite3 的 API 读取对应栏位资料
    while sqlite3_step(statement) == SQLITE_ROW{
    let id = Int(sqlite3_column_int(statement, 0))
    let title = String(cString: sqlite3_column_text(statement, 1))

    let amount = sqlite3_column_double(statement, 2)
    let createDate = String(cString: sqlite3_column_text(statement, 4))

    // 如果该笔记录有建立日期,且此日期尚未出现在 days 阵列中,则将日期加入并初始化该日的记录阵列及小计金额
    if createDate != "" {
    if !days.contains(createDate) {
    days.append(createDate)
    myRecords[createDate] = []
    eachDayAmount[createDate] = 0.0
    }

    // 单日小计,更新当日小计金额,加上当笔记录的金额
    eachDayAmount[createDate] = eachDayAmount[createDate]! + amount

    // 将该笔记录以字典形式加入对应日期的记录阵列中,并累计总金额
    myRecords[createDate]?.append([
    "id":"\\(id)",
    "title":"\\(title)",
    "amount":"\\(amount)"
    ])

    // 本月总计
    total += amount
    }
    }
    sqlite3_finalize(statement) // 完成资料读取后,释放 SQLite 资源

    myTableView.reloadData() // 重新载入 table view,让最新资料显示在介面上

    // 更新画面上总金额的显示文字
    amountLabel.text = String(format: "%g",total)

    }