
swift ui 如何使用sqlite
作者: boyyang
分类: Swift
发布: 2025-07-27 12:37:09
更新: 2025-07-27 12:37:09
浏览: 7
背景
在mac软件开发过程中需要将一些数据保存到用户电脑中,这些数据由于不和服务器交互,所以只能通过本地存储之类的。其实本地存储的方式有很多,有使用第三方存储方案的,同时swift 也有SwiftData等等方式用来存储本地数据。由于之前在做跨端开发的时候我使用了sqlite用来存储数据,所以打算在使用swift 开发原生应用中也采用sqlite。
我使用的是第三方的sqlite orm库,相比较我之前使用的gorm感觉要稍微复杂一点。
安装第三方sqlite orm库
在xcode中添加sqlite库
https://github.com/stephencelis/SQLite.swift.git
创建一个数据模型
我这里创建了一个收藏的模型,模型字段包括(id,like_id,like_name,like_path,w,h)
struct LikeModel: Decodable, Identifiable, Encodable {
var id: Int64
var like_id: String
var like_name: String
var like_path: String
var w: Int
var h: Int
func url () -> URL {
return URL(string: self.like_path)!
}
}
创建一个likeModelManager的class
通过Table()申明数据库表的名称,通过Expression来确定字段类型
class LikeModelManager {
static let shared = LikeModelManager()
private let db: Connection?
private let like = Table("like")
private let id = Expression<Int64>("id")
private let like_id = Expression<String>("like_id")
private let like_name = Expression<String>("like_name")
private let like_path = Expression<String>("like_path")
private let w = Expression<Int>("w")
private let h = Expression<Int>("h")
}
在初始化函数中连接sqlite文件
这里我省略了sqlite文件的创建,我这里是在应用启动的时候就做了sqlite文件的创建。通过FileManager的方法创建sqlite文件就可以了
private init() {
let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let dbPath = documentDirectory.appendingPathComponent("Desktop").appendingPathComponent("wallpaper.sqlite3")
do {
db = try Connection(dbPath.absoluteString)
createTable()
} catch {
db = nil
print("Unable to open database. Error: \(error)")
}
}
连接到sqlite文件后便可以初始化表了
可以通过ifNotExists来判断该表是否有创建,如果该表存在就会跳过该步骤
private func createTable() {
do {
try db?.run(like.create(ifNotExists: true){t in
t.column(id, primaryKey: true)
t.column(like_id)
t.column(like_name)
t.column(like_path)
t.column(w)
t.column(h)
})
} catch {
print("Unable to create table. Error: \(error)")
}
}
对表的一些操作
使用insert方法来插入数据
func addLike(like_id: String, like_name: String, like_path: String, w: Int, h: Int) -> Int64? {
if isExisit(id: like_id){
removeLike(id: like_id)
}else{
do {
let insert = like.insert(
self.like_id<-like_id,
self.like_name<-like_name,
self.like_path<-like_path,
self.w<-w,
self.h<-h,
)
let id = try db?.run(insert)
return id
} catch {
print("Insert failed. Error: \(error)")
return nil
}
}
return .zero
}
使用filter来筛选数据使用delete()删除对应数据
func removeLike(id: String) {
do {
let v = like.filter(like_id == id)
try db?.run(v.delete())
}catch{
print(error)
}
}
我这里贴一个完整代码,代码如下
//
// LikeModel.swift
// dotz
//
// Created by boyyang on 2025/7/4.
//
import SQLite
import Foundation
struct LikeModel: Decodable, Identifiable, Encodable {
var id: Int64
var like_id: String
var like_name: String
var like_path: String
var w: Int
var h: Int
func url () -> URL {
return URL(string: self.like_path)!
}
}
class LikeModelManager {
static let shared = LikeModelManager()
private let db: Connection?
private let like = Table("like")
private let id = Expression<Int64>("id")
private let like_id = Expression<String>("like_id")
private let like_name = Expression<String>("like_name")
private let like_path = Expression<String>("like_path")
private let w = Expression<Int>("w")
private let h = Expression<Int>("h")
private init() {
let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let dbPath = documentDirectory.appendingPathComponent("Desktop").appendingPathComponent("wallpaper.sqlite3")
do {
db = try Connection(dbPath.absoluteString)
createTable()
} catch {
db = nil
print("Unable to open database. Error: \(error)")
}
}
private func createTable() {
do {
try db?.run(like.create(ifNotExists: true){t in
t.column(id, primaryKey: true)
t.column(like_id)
t.column(like_name)
t.column(like_path)
t.column(w)
t.column(h)
})
} catch {
print("Unable to create table. Error: \(error)")
}
}
func addLike(like_id: String, like_name: String, like_path: String, w: Int, h: Int) -> Int64? {
if isExisit(id: like_id){
removeLike(id: like_id)
}else{
do {
let insert = like.insert(
self.like_id<-like_id,
self.like_name<-like_name,
self.like_path<-like_path,
self.w<-w,
self.h<-h,
)
let id = try db?.run(insert)
return id
} catch {
print("Insert failed. Error: \(error)")
return nil
}
}
return .zero
}
func removeLike(id: String) {
do {
let v = like.filter(like_id == id)
try db?.run(v.delete())
}catch{
print(error)
}
}
func allLikeIds() -> [String]{
var ids: [String] = []
do {
for like in try db!.prepare(like) {
ids.append(like[like_id])
}
}catch{
print(error)
}
return ids
}
func isExisit(id: String) -> Bool{
do {
let v = like.filter(like_id == id)
if try db?.scalar(v.count) ?? 0 > 0 {
return true
}
}catch{
print(error)
}
return false
}
func likeList(page: Int, limit: Int) -> (data: [LikeModel], count: Int){
var likeModelList: [LikeModel] = []
var count: Int = .zero
do {
for d in try db!.prepare(like.limit(limit, offset: (page - 1) * limit).order(id.desc)) {
likeModelList.append(LikeModel(
id: d[id],
like_id: d[like_id],
like_name: d[like_name],
like_path: d[like_path],
w: d[w],
h: d[h],)
)
}
count = try db!.scalar(like.count)
}catch{
print(error)
}
return (likeModelList, count)
}
}