SwiftUI Sqlite如何存儲復雜對象(2020)
SwiftUI Sqlite如何存儲復雜對象
如何你有大量圖片或者復雜文本需要存儲,sqlite 的Blob類型將是你最佳的選擇
代碼
public func addNote(_ note:Note) -> Int64 {
let notes = Table("notes")
let body=Expression<SQLite.Blob>("body")
let sec_id=Expression<Int64>("section_id")
let date=Expression<Double>("date")
let cloud_id=Expression<String>("cloud_id")
let locked=Expression<Bool>("locked")
let checksum=Expression<Int>("checksum")
let bytes=note.toBytes()
let cks=Note.checkSum(bytes: bytes)
let i = notes.insert(body <- SQLite.Blob(bytes: bytes),
sec_id <- note.section,
date <- note.date! ,
cloud_id <- note.cloud_id!,
checksum <- Int(cks),
locked<-note.locked)
do {
let rowid=try db?.run(i)
return rowid ?? -1
}catch {
print("Error info: \(error)")
}
return -1
}
數據截圖

定義了NoteObject父類
public class NoteObject : Identifiable {
public var id:Int=0
private var buffer:[UInt8]?
init() {
}
func getId() ->Int {
return id
}
func toBytes() -> [UInt8]? {
return buffer
}
static func bytesToInteger<Type>(_ from: [UInt8]) -> Type where Type: BinaryInteger {
return from.withUnsafeBufferPointer({
UnsafeRawPointer($0.baseAddress!).load(as: Type.self)
})
}
func toByteArray<Type>(_ value: Type) -> [UInt8] {
var unsafeValue = value
return withUnsafePointer(to: &unsafeValue) {
return $0.withMemoryRebound(to: UInt8.self, capacity: MemoryLayout<Type>.size, { pointer in
return [UInt8](UnsafeBufferPointer(start: pointer, count: MemoryLayout<Type>.size))
})
}
}
static func readInt(_ bytes: [UInt8], offset: inout Int) -> Int? {
guard bytes.count >= offset + MemoryLayout<Int>.size else { return nil }
let bytesForInt: [UInt8] = Array(bytes[offset..<offset + MemoryLayout<Int>.size])
let value: Int = bytesToInteger(bytesForInt)
offset += MemoryLayout<Int>.size
return value
}
static func readArray(_ bytes: [UInt8], offset: inout Int, capacity: Int, endOffset: Int) -> [UInt8]? {
if offset < endOffset {
let arr=bytes[offset...(offset+capacity-1)]
offset += arr.count
return Array(arr)
}
return nil
}
func debugString() {
print("element:\(type(of: self))")
if self is NoteText {
print(":"+(self as! NoteText).text)
} else if self is NoteImage {
print(":\((self as! NoteImage).image!.size)")
} else if self is NoteTable {
let table=(self as! NoteTable)
print(":\(table.text),\(table.nrow),\(table.ncol)")
}
}
}
NoteObject的子類
public class NoteText : NoteObject {
var text:String=""
var desc:String=""
init( text:String) {
self.text=text
}
init(newid: Int, text:String) {
super.init()
id=newid
self.text=text
self.desc=text
}
init (pk:Int,bytes:[UInt8],bytes2:[UInt8]) {
super.init()
id=pk
text=String(data: Data(bytes),encoding: .utf8)!
if bytes2.count > 0 {
desc=String(data: Data(bytes2),encoding: .utf8)!
}
}
override func toBytes() -> [UInt8]? {
var array = Array(text.utf8)
array.insert(contentsOf: toByteArray(array.count), at: 0)
array.insert(contentsOf: toByteArray(ObjectTags.text.rawValue), at: 0)
let array2 = Array(desc.utf8)
array.append(contentsOf: toByteArray(array2.count))
array.append(contentsOf: array2)
return array
}
}
public class NoteImage : NoteObject {
var image:UIImage?
var width:CGFloat=159
var height:CGFloat=150
init( image: UIImage) {
self.image=image
}
init(newid: Int, image: UIImage) {
super.init()
id=newid
self.image=image
}
init(pk:Int, bytes:[UInt8]) {
super.init()
id=pk
var offset = 0
let w=NoteObject.readInt(bytes, offset: &offset)
let h=NoteObject.readInt(bytes, offset: &offset)
if w! > 0 {
width=CGFloat(w!)
}
if h! > 0 {
height=CGFloat(h!)
}
let arr_bytes=NoteObject.readArray(bytes, offset: &offset, capacity: bytes.count-16, endOffset: bytes.count)
image=UIImage(data: Data.fromDatatypeValue(Blob(bytes: arr_bytes!)))!
}
override func toBytes() -> [UInt8]? {
let dimg = image!.jpegData(compressionQuality: 1.0)
var array=[UInt8]()
array.reserveCapacity((dimg!.count+1+8+8+8))
array.append(contentsOf: toByteArray(ObjectTags.image.rawValue))
array.append(contentsOf: toByteArray(dimg!.count+16))
array.append(contentsOf: toByteArray(Int(width)))
array.append(contentsOf: toByteArray(Int(height)))
array.append(contentsOf: dimg!)
return array
}
}
public class NoteTable : NoteObject {
var nrow:UInt8=0
var ncol:UInt8=0
var text:String=""
init( ncol:UInt8,nrow:UInt8, text:String) {
self.ncol=ncol
self.nrow=nrow
self.text=text
}
init(newid: Int, ncol:UInt8,nrow:UInt8, text:String) {
super.init()
id=newid
self.ncol=ncol
self.nrow=nrow
self.text=text
}
init (pk:Int,bytes:[UInt8]) {
super.init()
id=pk
self.ncol=bytes[0]
self.nrow=bytes[1]
text=String(data: Data(bytes[2...bytes.count-1]),encoding: .utf8)!
}
override func toBytes() -> [UInt8]? {
var array = Array(text.utf8)
let all_length=array.count+2
array.insert(contentsOf: toByteArray(nrow), at: 0)
array.insert(contentsOf: toByteArray(ncol), at: 0)
array.insert(contentsOf: toByteArray(all_length), at: 0)
array.insert(contentsOf: toByteArray(ObjectTags.table.rawValue), at: 0)
return array
}
}
來源
更多SwiftUI教程和代碼關注專欄
- 請關注我的專欄 SwiftUI教程與源碼
智能推薦
SwiftUI APP如何取代AppDelegate和SceneDelegate
SwiftUI是構建應用程序的好方法。簡單,簡潔,快速。可以用一半的代碼行在SwiftUI中重新創建UIKit中的內容。以前需要數周才能完成的工作現在只需幾個小時。但是直到今天,它還是有一個嚴重的缺點:它依賴于UIKit。 要顯示使用SwiftUI創建的視圖,您必須將其包裝在UIHostingController中,該包裝必須包裝在UIWindow中,而UIWindow必須在SceneDelega...
SwiftUI 中級List如何添加新內容(2020年教程)
功能說明 如何使用List循環顯示array內容 .self 作為id的使用 如何更新List內容 TextField基礎使用 代碼 效果 [email protected] 更多SwiftUI教程和代碼關注專欄 請關注我的專欄 SwiftUI教程與源碼...
SwiftUI guard 是什么如何用(2020教程)
guard 是一種控制流語句 通俗講guard和if-else、switch同屬于控制流范疇語句,if-esle和switch都屬于上古語句歷史悠久,guard肯定是后來者。 后來者的出現肯定是要解決一些前人無法解決的問題。記得有位大神說過“當你開始寫switch時,你代碼就開始墮落了”,可見switch語句時多么不受高手們的喜愛。 guard是swift 2.0引入的,他...
SwiftUI 中級之List顯示Sqlite數據庫內容(2020年教程)
SwiftUI 中級之List顯示Sqlite數據庫內容(2020年教程) 數據介紹 我們手動創建一個landmark.db 文件,其包含一個landmark表。表內容如下圖 SwiftUI 中級之List顯示Sqlite數據庫內容 csv文件 屬性 純Swift代碼 可以自定義table名稱 使用SwiftUI進行顯示 使用方法 如何加入到你到項目 (1) copy file to your p...
SwiftUI-Day2 復雜數據類型
文章目錄 吐槽 結果 初始化 數組-Arrays 集合-Sets 元組-Tuples 怎么選擇 字典- Dictionaries 創建空集合 - Collections Enumerations Enum associated values Enum raw values 吐槽 Xcode升級,什么appdelegate都沒有了,現在全是swiftUI。。。 下面的代碼是playground的代碼...
猜你喜歡
SwiftUI JSON文件下載、存儲、解析和展示(代碼大全)
JSON 簡介 JSON(JavaScript Object Notation, JS 對象簡譜) 是一種輕量級的數據交換格式。它基于 ECMAScript (歐洲計算機協會制定的js規范)的一個子集,采用完全獨立于編程語言的文本格式來存儲和表示數據。簡潔和清晰的層次結構使得 JSON 成為理想的數據交換語言。 易于人閱讀和編寫,同時也易于機器解析和生成,并有效地提升網絡傳輸效率。 我們通常從服務...
SwiftUI讀寫文件基礎操作,解決文件存儲問題
看完本文您將學習到 App基本目錄結構 如何存儲和讀取文件 如何將class和struct對象存儲到文件中 如何將存儲到文件中到數據再讀取回來 當您的應用程序不運行或設備關閉時,您的應用程序可以將數據保存到持久保存在設備中的文件中。本章介紹如何以及在何處保存和檢索文件。它還討論了可操縱文件的其他一些方式,例如應用程序如何彼此共享以及與云共享文檔。本章還說明了如何在“用戶默認設置&rdq...
freemarker + ItextRender 根據模板生成PDF文件
1. 制作模板 2. 獲取模板,并將所獲取的數據加載生成html文件 2. 生成PDF文件 其中由兩個地方需要注意,都是關于獲取文件路徑的問題,由于項目部署的時候是打包成jar包形式,所以在開發過程中時直接安照傳統的獲取方法沒有一點文件,但是當打包后部署,總是出錯。于是參考網上文章,先將文件讀出來到項目的臨時目錄下,然后再按正常方式加載該臨時文件; 還有一個問題至今沒有解決,就是關于生成PDF文件...
電腦空間不夠了?教你一個小秒招快速清理 Docker 占用的磁盤空間!
Docker 很占用空間,每當我們運行容器、拉取鏡像、部署應用、構建自己的鏡像時,我們的磁盤空間會被大量占用。 如果你也被這個問題所困擾,咱們就一起看一下 Docker 是如何使用磁盤空間的,以及如何回收。 docker 占用的空間可以通過下面的命令查看: TYPE 列出了docker 使用磁盤的 4 種類型: Images:所有鏡像占用的空間,包括拉取下來的鏡像,和本地構建的。 Con...