swift 使用 sqlite3 插入数组转 Data 类型错误

sinat_37001593 2017-01-12 01:12:24
把数组通过 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
}

}
...全文
116 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
scribbler 2017-01-16
  • 打赏
  • 举报
回复
\u7b2c\u4e00\u4e2a 是Unicode编码的,你需要将其转换成GBK编码

let str:String       = "123\u{7b2c}\u{4e00}\u{4e2a}"
let enc              = CFStringConvertEncodingToNSStringEncoding(UInt32(CFStringEncodings.GB_18030_2000.rawValue))
let data             = str.data(using: String.Encoding(rawValue: enc), allowLossyConversion: false)
let result:NSString  = NSString(data: data!, encoding: enc)!
print("\(result)")
sinat_37001593 2017-01-12
  • 打赏
  • 举报
回复
引用 2 楼 scribbler 的回复:
insert代码有误 1、需要将痛殴NSData数据转化成bytes, 2、在插入数据库时采用blob方式插入 希望对你有帮助

func insert(results: [[String: Any]])
{
    let data = NSKeyedArchiver.archivedData(withRootObject: results)
    let array = data.withUnsafeBytes {
        [UInt8](UnsafeBufferPointer(start: $0, count: data.count))
    }
    
    let insertSQL = "INSERT INTO t_models (results) VALUES (?);"
    var statement: OpaquePointer?
    if sqlite3_prepare_v2(db, insertSQL, -1, &statement, nil) == SQLITE_OK
    {
        sqlite3_bind_blob(statement, 1, array, Int32(data.count), nil)
        sqlite3_step(statement)
        sqlite3_finalize(statement)
    }
    else
    {
        print( "Failed from sqlite3_prepare_v2. Error is:  %s", sqlite3_errmsg(db) )
    }
}
谢谢你,数据能取出来了,只不过中文的数据是\U7b2c\U4e00\U4e2a类似的,不是中文
scribbler 2017-01-12
  • 打赏
  • 举报
回复
insert代码有误 1、需要将痛殴NSData数据转化成bytes, 2、在插入数据库时采用blob方式插入 希望对你有帮助

func insert(results: [[String: Any]])
{
    let data = NSKeyedArchiver.archivedData(withRootObject: results)
    let array = data.withUnsafeBytes {
        [UInt8](UnsafeBufferPointer(start: $0, count: data.count))
    }
    
    let insertSQL = "INSERT INTO t_models (results) VALUES (?);"
    var statement: OpaquePointer?
    if sqlite3_prepare_v2(db, insertSQL, -1, &statement, nil) == SQLITE_OK
    {
        sqlite3_bind_blob(statement, 1, array, Int32(data.count), nil)
        sqlite3_step(statement)
        sqlite3_finalize(statement)
    }
    else
    {
        print( "Failed from sqlite3_prepare_v2. Error is:  %s", sqlite3_errmsg(db) )
    }
}
scribbler 2017-01-12
  • 打赏
  • 举报
回复
insert代码误 1、需要将痛殴NSData数据转化成bytes, 2、在插入数据库时采用blob方式插入 希望对你有帮助

func insert(results: [[String: Any]])
    {
        let data = NSKeyedArchiver.archivedData(withRootObject: results)
        let array = data.withUnsafeBytes {
            [UInt8](UnsafeBufferPointer(start: $0, count: data.count))
        }
        
        let insertSQL = "INSERT INTO t_models (results) VALUES (?);"
        var statement: OpaquePointer?
        if sqlite3_prepare_v2(db, insertSQL, -1, &statement, nil) == SQLITE_OK
        {
            sqlite3_bind_blob(statement, 1, array, Int32(data.count), nil)
            sqlite3_step(statement)
            sqlite3_finalize(statement);
        }
        else
        {
            print( "Failed from sqlite3_prepare_v2. Error is:  %s", sqlite3_errmsg(db) )
        }
    }

29,027

社区成员

发帖
与我相关
我的任务
社区描述
主要讨论与iOS相关的软件和技术
社区管理员
  • iOS
  • 大熊猫侯佩
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧