Reputation: 21
I recently started an iOS project and need to work with a standalone database that'll be downloaded from the internet when there are updates. This is my first iOS project, so am trying to get functionality working before designing the download mechanism.
I've selected the SQLite wrapper SWLite.swift
(https://github.com/stephencelis/SQLite.swift) and have my queries and table views ready to roll. But I can't connect to the DB. I've tried just about every other question/answer on here with absolutely no success.
For example, I dropped the SQLite database into the Assets.xcassets
and tried let path = Bundle.main.path(forResource: "myDb", ofType: "db")!
, and the app crashes (as I got nil
back -- presumably because the path couldn't be located). LikewiseI tried what others suggested, including creating a folder on my Mac, dropping the file into it, appending .bundle
to the folder name, and dropping that into the Assets... again, nil
.
Could anybody advise? I've looked at the Apple Docs and couldn't really find what I was looking for -- again, this is my first time, so maybe I'm doing it wrong.
Upvotes: 2
Views: 3220
Reputation: 2022
Looks like your actual main problem was getting a valid path to your database file. I couldn't find any way to make it work, if the database file is located in the Assets, either. So don't save the database file in your Assets folder, but add it to your Copy Bundle Resources list in the Build Phases setting of your current target. If your file is called myDb.db
you can then get a valid path like this:
let dbUrl = Bundle.main.url(forResource: "myDb", withExtension: "db")!
let dbPath = dbUrl.path
It is possible to access your database now without having to (manually?) copy it. Just use the already mentioned SQLite.swift library:
db = try! Connection(dbPath)
Notes: As the question is a little bit older aleady, maybe it wasn't possible to access the database file like this at the time of asking. However, it does work by now. The only thing I haven't checked yet explicitly is writing to the database. At least a read-only access does work like a charm though.
Upvotes: 3
Reputation: 1389
First off, you never want to have your db anywhere else except in your Documents Folder.
Here's the process to do with SQLite.Swift:-
// this is the path where your DB should be
let path = NSSearchPathForDirectoriesInDomains(
.documentDirectory, .userDomainMask, true
).first!
// this is how you create a DB with a table:-
do {
let db_name = "my_db"
let db = try Connection("\(path)" + "/" + db_name! + ".sqlite3")
try db.key("12345") // if db is encrypted with SQLCipher
do {
try db.run(mastertableName.create(ifNotExists: true) { t in
t.column(database_name)
t.column(email, unique: true)
t.column(date_created)
t.column(device_info)
})
}
catch {
print("Creating Master Table Failed!")
}
Just by doing a connection, it will create a DB for you, if it doesn't exists!!
Reading the DB:-
do {
let db_name = "my_db"
let db = try Connection("\(path)" + "/" + db_name! + ".sqlite3")
try db.key("12345")
// db is now open... do your stuff..
}
catch {
print("opening the db failed!")
}
Upvotes: -1
Reputation: 25261
You cannot directly read from bundle sqlite files on your phone. You have to first copy it into Documents folder and start reading from there. This only needs to be done once. To move it,
let path = Bundle.main.path(forResource: "DBName", ofType: "sqlite")
do{
try fileManger.copyItem(atPath: path!, toPath: dbPath)
}catch let error as NSError {
print("error occurred, here are the details:\n \(error)")
}
Then to connect, you can use
let doumentDirectoryPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString
let dbPath = doumentDirectoryPath.appendingPathComponent("DBName.sqlite")
Upvotes: 1