BOYYANG/1/blog/compressed/《崩坏星穹铁道》流萤 午后 壁纸高清4k_彼岸图网-f88c757bdd202ee8da6f614a690a9b90

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

     

#swift
#swift ui
#sqlite