Swift SQLite Error

Hello,
I am very new to programming, Swift, Xcode and SQLite. I have researched the possible answer to this issue but I feel I need some expert help to understand this further please.

I have an example Swift program that enters data into, out etc from SQLite database. I have not included all sections of this program but only the function where the error is. The entire function is listed at the bottom of this question.

The error that shows is "Value of type '[NSString]' has no member 'utf8String'" and only appears on the line "sqlite3bindtext(insertStatement, 3, address.utf8String, -1, nil)".

In the code at the bottom of this question, The line above the error line performs the same database input function for column 2 and is prefixed with "name.utf8String" but it does not have any error and when I remove the Error line the program runs and performs as expected.

This error is stating that it is a "Type" error which my research has uncovered relates to variables, arrays and ints etc where the data type is trying to be converted to another data type. However from the NSString type documents, it says that it can convert to utf8String along with other types, so I am not sure why this particular line shows an error and the one before does not and how to fix it.

Can you please help me to understand this further and how to fix it please?

func insertname() {
  var insertStatement: OpaquePointer?

    let name: [NSString] = ["Ray", "Chris", "Martha", "Danielle"]

    let address: [NSString] = ["EducationRd", "HillRd", "ValleyDr", "SouthRd"]

  //  let str = NSString(decoding: address, as:UTF8.self)

    if sqlite3preparev2(db,insertStatementString,-1,&insertStatement,nil) == SQLITEOK {

    print("\n MULTIPLE NAME INSERTS CHALLENGE: NAMES IN ARRAY = \(name)")

    print("\n MULTIPLE ADDRESS INSERTS CHALLENGE: ADDRESSES IN ARRAY = \(address)")

    for (index, name) in name.enumerated() {


      let id = Int32(index + 1)

        sqlite3
bindint(insertStatement, 1, id)

      sqlite3
bindtext(insertStatement, 2, name.utf8String, -1, nil)

      sqlite3
bindtext(insertStatement, 3, address.utf8String, -1, nil)

      if sqlite3
step(insertStatement) == SQLITEDONE {

        print("SUCCESSFULLY INSERTED ROW ID = \(id), NAME = \(name), ADDRESS = \(address)")

      } else {

        print("COULD NOT INSERT ROW. ID = \(id), NAME = \(name), ADDRESS = \(address)")

      }

      sqlite3
reset(insertStatement)

    }

    sqlite3_finalize(insertStatement)

  } else {

    print("SUCCESSFULLY INSERTED ROW.")

  }

}
First of all.
It is very hard to use SQLite3 directly in Swift even for experienced programmers.
I would never recommend it for people who are very new to programming.

You should better spend your time learning Core Data or some other third party libraries instead of using SQLite3.


Second, use String instead of NSString in Swift, as far as you can.

Third, utf8String is sort of a fragile property. You should better avoid using it.

Forth, in your code, address is an Array of NSString, NOT NSString. You cannot use the property utf8String for an Array, it is a property of NSString.

Fifth, you may want to pair each element of name and address, but your code has nothing to do pairing.

Sixth, your name represents two different things, in some context, it is an Array of NSString, in some other context, it is an NSString.
This is confusing. You should better avoid using the same name for two different things.

And the last, though very important, you should use Code block feature of this site, when inserting code as text, indicated by the icon <>.

All such things considered, I would rewrite your code as follows:
Code Block
func insertname() {
var insertStatement: OpaquePointer?
let names: [String] = ["Ray", "Chris", "Martha", "Danielle"] //<- Use plural form, use `String` instead of `NSString`
let addresses: [String] = ["EducationRd", "HillRd", "ValleyDr", "SouthRd"] //<- Use plural form, use `String` instead of `NSString`
if sqlite3_prepare_v2(db, insertStatementString, -1, &insertStatement, nil) == SQLITE_OK {
print("\n MULTIPLE NAME INSERTS CHALLENGE: NAMES IN ARRAY = \(names)")
print("\n MULTIPLE ADDRESS INSERTS CHALLENGE: ADDRESSES IN ARRAY = \(addresses)")
for (index, (name, address)) in zip(names, addresses).enumerated() { //<- Pair `names` and `addresses`
name.withCString {namePtr in
address.withCString {addressPtr in
let id = Int32(index + 1)
sqlite3_bind_int(insertStatement, 1, id)
sqlite3_bind_text(insertStatement, 2, namePtr, -1, nil)
sqlite3_bind_text(insertStatement, 3, addressPtr, -1, nil)
if sqlite3_step(insertStatement) == SQLITE_DONE {
print("SUCCESSFULLY INSERTED ROW ID = \(id), NAME = \(name), ADDRESS = \(address)")
} else {
print("COULD NOT INSERT ROW. ID = \(id), NAME = \(name), ADDRESS = \(address)")
}
sqlite3_reset(insertStatement)
}
}
}
sqlite3_finalize(insertStatement)
} else {
print("SUCCESSFULLY INSERTED ROW.")
}
}

(Not tested. You may need more fixes.)
Swift SQLite Error
 
 
Q