Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
390 views
in Technique[技术] by (71.8m points)

ios - Issue with UnsafePointer<Uint8> in SQLite project in Swift

We are implementing SQLite in iOS, in Swift, without using wrappers or Objective-C bridging. Everything works fine, except when doing a query and extracting the result. The issue is with the UnsafePointer<UInt8> that is returned from SQLite in Swift as follows:

var querySQL = "SELECT address, phone FROM CONTACTS WHERE NAME = 'myName'"
var cQuery = querySQL.cStringUsingEncoding(NSUTF8StringEncoding)
var statement: COpaquePointer = nil
if sqlite3_prepare_v2(contactsDB, cQuery!, -1, &statement, nil) == SQLITE_OK {
   if sqlite3_step(statement) == SQLITE_ROW {
   var address : UnsafePointer<UInt8> = sqlite3_column_text(statement, 0)
   var data = NSData(bytes: address, length: 10)
   var string = NSString(data: data, encoding: NSUTF8StringEncoding)
   println(string)

As you can see, we can convert the pointer to String if we know the length of the object (in this case 10)

To dig into this issue, I have the following example

let pointerFromString: UnsafePointer<Int8> = "xyz".cStringUsingEncoding(NSUTF8StringEncoding)
let stringFromPointer = String.fromCString(anotherPointerFromString_Int8)                    println(stringFromPointer!)

Given that CChar is an alias of Int8, I can convert a String to UnsafePointer<Int8> using .cStringUsingEncoding(), and then back to String using .fromCString(<UnsafePointer_CChar>)

The problem is that my SQLite result is a UnsafePointer_UInt8, that can′t be used with .fromCString()

The bottom line question is: Is it possible to convert or cast a UnsafePointer_UInt8 to UnsafePointer_Int8

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This should work:

let address = sqlite3_column_text(statement, 0)
let string = String.fromCString(UnsafePointer<CChar>(address))

Update for Swift 3 (Xcode 8), compare Swift 3: convert a null-terminated UnsafePointer<UInt8> to a string:

let string = String(cString: sqlite3_column_text(statement, 0))

Update:

sqlite3_column_text() returns an implicitly unwrapped optional, and that is why you can pass it to String(cString:) directly.

But according to Column methods, error and NULL handling #41, the return value can be null (in an out-of-memory situation, or if called with a NULL column type). Therefore it is safer to do

if let text = sqlite3_column_text(statement, 0) {
    let string = String(cString: text)
    // ...
} else {
    // sqlite3_column_text() returned NULL
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...