3

I'm using SwiftData for SQLite access.

https://github.com/mozilla-mobile/firefox-ios/blob/master/Storage/ThirdParty/SwiftData.swift

SwiftData is a SQLite wrapper coded in Swift. After Swift 3.0 and XCode 8 the following lines are broken. I'm sort of noobie with Swift so I would appreciate your help with fixing what is broken:

let text = UnsafePointer<Int8>(sqlite3_column_text(statement, index))

results to: "'init' is unavailable: use 'withMemoryRebound(to:capacity:_)' to temporarily view memory as another layout-compatible type."

return Data(bytes: UnsafePointer<UInt8>(blob), count: Int(size))

results to: "Cannot invoke initializer for type 'UnsafePointer' with an argument list of type '(UnsafeRawPointer?)'"

return sqlite3_column_int(statement, index) != 0

results to: "'!=' produces 'Bool', not the expected contextual result type 'AnyObject?'"

let text = UnsafePointer<Int8>(sqlite3_column_text(statement, index))

Results to: "'init' is unavailable: use 'withMemoryRebound(to:capacity:_)' to temporarily view memory as another layout-compatible type."

for i: Int32 in 0 ..< columnCount += 1 {

Results to: "Left side of mutating operator isn't mutable: '..<' returns immutable value"

All Help Appreciated!

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382
user594883
  • 1,329
  • 2
  • 17
  • 36
  • 1
    See http://stackoverflow.com/a/25169265/1187415 for the `sqlite3_column_text` problems. – Martin R Nov 02 '16 at 12:57
  • 1
    The last problem is a duplicate of http://stackoverflow.com/questions/39940937/error-in-for-loop-cgfloat (and why is there a `+= 1` in the loop at all?) – Martin R Nov 02 '16 at 12:59
  • For the *"'!=' produces 'Bool', not the expected contextual result type 'AnyObject?'"* problem we would need to know more context: What does the function return? – Martin R Nov 02 '16 at 13:03
  • @MartinR Sorry, forgot to add link to github for source code. Please see the edited post. I was wondering on the "+= 1" myself. – user594883 Nov 02 '16 at 13:19
  • @MartinR For the `!= produces Bool, not the expected contextual result type AnyObject?` the function is (after XCode Swift 3.0 migration tool) `func getColumnValue(_ statement: OpaquePointer, index: Int32, type: String) -> AnyObject? {` – user594883 Nov 02 '16 at 14:27
  • Since https://github.com/ryanfowler/SwiftData is not maintained, why don't you switch to a Swift wrapper that is up to date, like https://github.com/groue/GRDB.swift? – Gwendal Roué Nov 02 '16 at 16:20
  • @GwendalRoué I have a lot of SwiftData access in my app. I figured it was easier to fix the 5 places that had gone wrong in Swift 2 -> 3 migration than started to use another wrapper. But I think I might have to give your suggestion a try since the 5 simple fixes aren't so simple after all. Even after I got the code to compile, it crashes immediately at dataaccess. I'm mad at Swift 3 design to cause me extra work without apparent payback. – user594883 Nov 02 '16 at 19:45

1 Answers1

1

sqlite3_column_int(statement, index) returns an Int32 and

sqlite3_column_int(statement, index) != 0

is a boolean value, so that makes no sense as the return value if an (optional) AnyObject is expected. You can wrap the integer into a NSNumber instead:

func getColumnValue(_ statement: OpaquePointer, index: Int32, type: String) -> AnyObject? {
    let val = sqlite3_column_int(statement, index)
    return NSNumber(value: val)
}

Another option would be

func getColumnValue(_ statement: OpaquePointer, index: Int32, type: String) -> AnyObject? {
    return sqlite3_column_int(statement, index) as AnyObject
}

because in Swift 3, anything can be converted to AnyObject. The difference is that in the second solution, the object can only be converted back to the original number type Int32, but not to Int or any other integer type.

For the other problems, see

Community
  • 1
  • 1
Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382