问题描述
我正在开发使用Pencilkit的应用程序。我试图将PK绘图以数据的形式保存在sqlite3数据库中,但未保存。我认为问题出在保存功能,而不是获取要显示的绘图数据的功能,因为当我直接在终端中查询时,数据库中的绘图行为空。
func save(canvas: Canvas) {
// connect to database
connect()
// canvas.drawing is already in the form of data not PK drawing here
let drawingData = canvas.drawing
drawingData.withUnsafeBytes { drawingBuffer in
let drawingPtr = drawingBuffer.baseAddress!
var statement: OpaquePointer!
if sqlite3_prepare_v2(database,"UPDATE drawings SET drawing = ? WHERE rowid = ?",-1,&statement,nil) != sqlITE_OK {
print("Could not create (update) query")
}
sqlite3_bind_blob(statement,1,drawingPtr,nil)
sqlite3_bind_int(statement,2,Int32(canvas.id))
if sqlite3_step(statement) != sqlITE_DONE {
print("Could not execute update statement")
}
sqlite3_finalize(statement)
}
}
解决方法
一些观察结果:
-
对于
sqlite3_bind_blob
,第四个参数是大小,这是必需的,并且不能为负数。使用sqlite3_bind_text
,您可以提供一个-1
值,因为C字符串以null结尾,并且可以弄清楚字符串的结尾,但是不能用blob做到这一点。如果
sqlite3_bind_blob()
的第四个参数为负,则行为未定义。因此,也许:
guard let blob = drawingBuffer.baseAddress else { return } let count = Int32(drawingBuffer.count)
然后:
sqlite3_bind_blob(statement,1,blob,count,nil)
-
此外,如果SQLite调用失败,则应打印错误,否则将导致盲目飞行,例如
let errorMessage = sqlite3_errmsg(database).map { String(cString: $0) } ?? "Unknown error" print("failure preparing UPDATE statement: \(errorMessage)")
每当您检查SQLite返回代码时,都应该这样做。通常,这将使诊断呼叫失败的原因变得更加容易。