swift 使用 sqlite3 插入数组转 Data 类型错误
把数组通过 NSKeyedArchiver.archivedData(withRootObject: array) 转成 Data 类型后存入数据库,取出的时候通过将 Data 数据再转回来 NSKeyedUnarchiver.unarchiveObject(with: data),但是取出的值却是空。求教,存入时用的是 BLOB 类型.
源代码:https://github.com/Zane6w/SQL
import UIKit
class SQLManager: NSObject {
static let shared = SQLManager()
var db: OpaquePointer?
var dataLength: Int?
/// 创建并打开数据库
func openDB() -> Bool {
var filePath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first
filePath! += "/data.sqlite"
let cFilePath = (filePath?.cString(using: .utf8))!
if sqlite3_open(cFilePath, &db) != SQLITE_OK {
print("数据库开启失败")
return false
}
return createTable()
}
/// 制表
func createTable() -> Bool {
let createTableSQL = "CREATE TABLE IF NOT EXISTS 't_models' ( 'id' INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,'results' BLOB);"
return execSQL(sql: createTableSQL)
}
/// 执行
func execSQL(sql: String) -> Bool {
let cSql = (sql.cString(using: .utf8))!
return sqlite3_exec(db, cSql, nil, nil, nil) == SQLITE_OK
}
func querySQL(querySQL: String) -> [[String: Any]]? {
// 定义游标对象
var stmt: OpaquePointer?
// 将出查询语句转换为C语言字符串
let cQuery = (querySQL.cString(using: .utf8))!
// 查询准备工作
if sqlite3_prepare_v2(db, cQuery, -1, &stmt, nil) != SQLITE_OK {
print("没有准备好")
return nil
}
// 准备好了
var tempArr = [[String: Any]]()
while sqlite3_step(stmt) == SQLITE_ROW {
// 获取列的个数
let count = sqlite3_column_count(stmt)
// 遍历
var dict = [String: Any]()
for i in 0..<count {
let cKey = sqlite3_column_name(stmt, i)
let key = String(cString: cKey!, encoding: .utf8)
let cValue = sqlite3_column_blob(stmt, i)
let countData = sqlite3_column_bytes(stmt, i)
let data = Data(bytes: cValue!, count: Int(countData))
dict[key!] = data
}
// 字典放入数组中
tempArr.append(dict)
}
return tempArr
}
/// 插入数据
func insert(results: [[String: Any]]) {
let data = NSKeyedArchiver.archivedData(withRootObject: results)
// 插入 SQL
let insertSQL = "INSERT INTO t_models (results) VALUES ('\(data)');"
if self.execSQL(sql: insertSQL) {
print("数据插入成功")
} else {
print("数据插入失败")
}
}
/// 读取数据
func loadData() -> [Any]? {
let querySQL = "SELECT results FROM t_models;"
let dictArr = self.querySQL(querySQL: querySQL)
// 判断数组如果有值, 则遍历, 并且转成模型对象, 放入另外一个数组中
if let temoDictArr = dictArr {
var tempArr = [Any]()
for dict in temoDictArr {
let data = dict["results"] as! Data
let res = NSKeyedUnarchiver.unarchiveObject(with: data)
tempArr.append(res)
}
return tempArr
}
return nil
}
}
源代码:https://github.com/Zane6w/SQL
import UIKit
class SQLManager: NSObject {
static let shared = SQLManager()
var db: OpaquePointer?
var dataLength: Int?
/// 创建并打开数据库
func openDB() -> Bool {
var filePath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first
filePath! += "/data.sqlite"
let cFilePath = (filePath?.cString(using: .utf8))!
if sqlite3_open(cFilePath, &db) != SQLITE_OK {
print("数据库开启失败")
return false
}
return createTable()
}
/// 制表
func createTable() -> Bool {
let createTableSQL = "CREATE TABLE IF NOT EXISTS 't_models' ( 'id' INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,'results' BLOB);"
return execSQL(sql: createTableSQL)
}
/// 执行
func execSQL(sql: String) -> Bool {
let cSql = (sql.cString(using: .utf8))!
return sqlite3_exec(db, cSql, nil, nil, nil) == SQLITE_OK
}
func querySQL(querySQL: String) -> [[String: Any]]? {
// 定义游标对象
var stmt: OpaquePointer?
// 将出查询语句转换为C语言字符串
let cQuery = (querySQL.cString(using: .utf8))!
// 查询准备工作
if sqlite3_prepare_v2(db, cQuery, -1, &stmt, nil) != SQLITE_OK {
print("没有准备好")
return nil
}
// 准备好了
var tempArr = [[String: Any]]()
while sqlite3_step(stmt) == SQLITE_ROW {
// 获取列的个数
let count = sqlite3_column_count(stmt)
// 遍历
var dict = [String: Any]()
for i in 0..<count {
let cKey = sqlite3_column_name(stmt, i)
let key = String(cString: cKey!, encoding: .utf8)
let cValue = sqlite3_column_blob(stmt, i)
let countData = sqlite3_column_bytes(stmt, i)
let data = Data(bytes: cValue!, count: Int(countData))
dict[key!] = data
}
// 字典放入数组中
tempArr.append(dict)
}
return tempArr
}
/// 插入数据
func insert(results: [[String: Any]]) {
let data = NSKeyedArchiver.archivedData(withRootObject: results)
// 插入 SQL
let insertSQL = "INSERT INTO t_models (results) VALUES ('\(data)');"
if self.execSQL(sql: insertSQL) {
print("数据插入成功")
} else {
print("数据插入失败")
}
}
/// 读取数据
func loadData() -> [Any]? {
let querySQL = "SELECT results FROM t_models;"
let dictArr = self.querySQL(querySQL: querySQL)
// 判断数组如果有值, 则遍历, 并且转成模型对象, 放入另外一个数组中
if let temoDictArr = dictArr {
var tempArr = [Any]()
for dict in temoDictArr {
let data = dict["results"] as! Data
let res = NSKeyedUnarchiver.unarchiveObject(with: data)
tempArr.append(res)
}
return tempArr
}
return nil
}
}
...全文
相关推荐
swift创建数据库、模型转字典、封装选择视图
在Swift编程中,数据库操作、模型转换为字典以及UI组件的封装是常见的开发任务。以下将详细讲解这些知识点。一、Swift创建数据库在Swift中,常用的数据库框架有Core Data和SQLite。
Swift学习教程之SQLite的基础使用
Swift学习教程之SQLite的基础使用本文主要介绍了Swift学习教程之SQLite的基础使用,通过示例代码详细介绍了SQLite的基础使用。
swift-FMDB使用教程--增删改查
### 关闭和释放数据库当不再需要数据库时,应该关闭并释放资源:```swiftdb.close()db = nil```以上就是使用Swift的FMDB库进行数据库操作的基本步骤,包括创建数据库、插入数据
Swift 操作数据库
在Swift中操作数据库通常涉及到使用SQLite或Core Data等框架。SQLite是一个轻量级的关系型数据库,而Core Data是苹果提供的一种对象图形管理器,适用于管理应用程序的数据模型。
iOS数据库SQLite3基本操作并将内容显示在tableView中
三、Swift版本对于Swift开发者,可以使用`FMDB`库,它是SQLite3的一个Swift封装,提供了更易用的接口。


