The48Percent
The48Percent

Reputation: 21

How to work with an existing SQLite database in iOS?

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

Answers (3)

Johnson_145
Johnson_145

Reputation: 2022

1.: Get a valid path to your database file

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

2.: Access your database (without copying it)

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

Dark Innocence
Dark Innocence

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

Fangming
Fangming

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

Related Questions