Why saving data to SQLite database doesn't work with Swift 2?
let db = try! Connection()
creates an in-memory database, as you can see from the API documentation:
/// Initializes a new SQLite connection.////// - Parameters:////// - location: The location of the database. Creates a new database if it/// doesn’t already exist (unless in read-only mode).////// Default: `.InMemory`.////// - readonly: Whether or not to open the database in a read-only state.////// Default: `false`.////// - Returns: A new database connection.public init(_ location: Location = .InMemory, readonly: Bool = false) throws
The data is not persisted to a file, and the database is always initiallyempty.
For a persistent database, use
/// Initializes a new connection to a database.////// - Parameters:////// - filename: The location of the database. Creates a new database if/// it doesn’t already exist (unless in read-only mode).////// - readonly: Whether or not to open the database in a read-only state.////// Default: `false`.////// - Throws: `Result.Error` iff a connection cannot be established.////// - Returns: A new database connection.public convenience init(_ filename: String, readonly: Bool = false) throws
instead, for example
// Compute file path for database in Documents directory:let docsDir = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).last!let dbPath = (docsDir as NSString).stringByAppendingPathComponent("database.sqlite")do { let db = try Connection(dbPath) // ... use database} catch (error) { // Could not create or open database, print error}
The viewDidLoad
first creates the table, then inserts.
I don't know the behavior of the table create function when the table already exists, but if it does not throw any errors on you, it probably recreates the table again. If that's the case, after calling the viewDidLoad
with the insert commented out, you probably end up with a fresh new blank table.
Try changing the logic making sure that the table is not recreated every time.
You could have something like this (Obviously everybody else could improve the code):
Create the model of your table:
class TUsers {static let TABLE_NAME : String = “users”static let ID = Expression<Int64>("id")static let EMAIL = Expression<String>(“email”)static let NAME = Expression<String>(“name”)class func addUser(email : String!, name : String!) -> Bool{ let users = Table(TABLE_NAME) do { try DBHelper.instance.db.run(users.insert( TUsers.EMAIL <- email, TUsers.NAME <- name )) return true } catch { print("Insert failed") return false }}class func getAllUsers() -> [User] { // you must create the model user let users = Table(TUsers.TABLE_NAME) let query = users.select(*) //.filter(TUsers.EMAIL == “whatever@pomberobota.com”) var listOfUsers : [Users] = [] for user in DBHelper.instance.db.prepare(query) { // Do whatever you need to instantiate the model User listOfUsers.append(User(email: users[TUsers.EMAIL], name: users[TUsers.NAME]) } return listOfUsers}}
Create a database helper
class DBHelper {static let instance = DBHelper()var db : Connectioninit() { do { self.db = try Connection("\(Util.getDBPath())/db.sqlite3") createTablesIfNotExists() } catch { print("Could not create a connection to database") }}func createTablesIfNotExists() { let users = Table(TUsers.TABLE_NAME) do { try db.run(logs.create(ifNotExists: true) { t in t.column(TUsers.ID, primaryKey: true) t.column(TUsers.EMAIL) t.column(TUsers.NAME) }) } catch { print(“Could not create table users”) }}}
And finally (here you don't need to import SQLite).
class ViewController: UIViewController {override func viewDidLoad() { super.viewDidLoad() TUsers.addUser(“user@ndetavysho.com”, “John Capuchon”) let users = TUsers.getAllUsers() for user in users { // do something }}
}