- 匯入 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)
}