Database error when testing on device

Hello everyone. I have the following problem. I have an application that queries a database in sqlite. When I run the app in xcode on my mac I give it the path to the database to make it work. So far so good. But when I want to test this application on a physical device (iPhone 11), I get the error that the application cannot find the database. My question or problem is where I have to store the database on the iPhone so that the application can make the queries. Thank you.

I am putting my db on app group directory so that the app and app widgets can access it:

let dbName = "my-db.sqlite"
let documentsDirectory = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.org.org-name.app-name")
let databaseURL = documentsDirectory?.appendingPathComponent(dbName)

Where do you want that database to be? Possible locations depending upon your use case: Document folder, Temporary folder (could be deleted by OS on a whim), Caches folder (ditto, but less aggressively), Application Support folder (don't remember off-hand if this one is writeable), App bundle (read-only). And if it is a pre-populated DB (rather than the one created from scratch) you'd need to copy it to the target location first (e.g. from your app bundle).

Tera, thank.First of all, thank you very much for answering me.I want the database to go with the application. That is, I have created the application on my mac and now I am testing it on my iphone. The problem is that I DON'T KNOW WHERE TO SAVE the database so that when I run the application on the iPhone it works. My application works perfectly on the iPhone, except when it has to perform a query, because it doesn't know where the database is, and that is my question, where do I have to put the database on the iPhone so that, when the application, you can make the query, because now, when you want to make the query, the application gives me an error and it doesn't work.

Thanks for the reply. But I have a question. When you say . "I am putting my db on app group directory so that the app and app widgets can access it:" I don't quite understand, do I have to put the database inside the application's file group in Xcode? As if it were a view?

Tera, thank.First of all, thank you very much for answering me.I want the database to go with the application. That is, I have created the application on my mac and now I am testing it on my iphone. The problem is that I DON'T KNOW WHERE TO SAVE the database so that when I run the application on the iPhone it works. My application works perfectly on the iPhone, except when it has to perform a query, because it doesn't know where the database is, and that is my question, where do I have to put the database on the iPhone so that, when the application, you can make the query, because now, when you want to make the query, the application gives me an error and it doesn't work.

If I understand your task correctly - your database is writeable (not just used for read-only queries). If that's the case I'd do something like this:

  1. put your DB file in Xcode project normally, make sure it gets into the resulting binary (check Target Membership property of that file).
  2. on app startup check Documents folder location (e.g. .../Documents/database.db)
    2.a if the file is not there - copy it from your bundle location
    2.b if the file is already there - it was already copied (on previous app launches), do nothing
  3. after that point your code to use DB in the document folder location.
extension URL {
    static var documentsDir: URL {
        let array = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
        let path = array.first.unwrap()
        return URL(fileURLWithPath: path)
    }
    var fileExists: Bool {
        FileManager.default.fileExists(atPath: path)
    }
}

var dbFile: URL!

func onLaunch() {
    dbFile = URL.documentsDir.appendingPathComponent("database.db")
    if !dbFile.fileExists {
        let sourceFile = Bundle.main.url(forResource: "database.db", withExtension: nil)!
        try! FileManager.default.copyItem(at: sourceFile, to: dbFile)
    }
}

In addition to that if you specify "Application supports iTunes file sharing: true" in the project's plist file you'll be able to import / export that file from your app when you connect your iPhone to the computer (Devices → your device → Your app → Files tab) - might be convenient for debugging, or as a user feature.

Thanks again for answering me. I tell you. The database is READ ONLY, depending on the option chosen by the user, the application performs a query with the database (sqlite) and it returns some data. This the first.The second thing I don't understand about itunes. I beg your patience because I am new to this and I have no idea, for me this is completely new. Could you explain to me step by step how to do what you say? I beg your patience and thank you very much for everything.

hanks again for answering me. I tell you. The database is READ ONLY, depending on the option chosen by the user, the application performs a query with the database (sqlite) and it returns some data. This the first.The second thing I don't understand about itunes. I beg your patience because I am new to this and I have no idea, for me this is completely new. Could you explain to me step by step how to do what you say? I beg your patience and thank you very much for everything.

Then, assuming SQLite can work with the DB from a readonly location †, just place the DB in Xcode's project:

And use in the app like so:

let dbFile = Bundle.main.url(forResource: "database.db", withExtension: nil)!
... use dbFile ...

Change the DB file name accordingly.

(† and if SQLite can't work with a read-only file then follow the approach I outlined in the previous post).

Please note that questions like these are out of scope on this forum and better asked on stackoverflow or apple dev forums.

1 Like

I am reading json files delivered within the app using this approach, so I'd assume reading (read only) SQLite database files would work too. Haven't tried though.

1 Like