Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where to locate Sqlite database in Xcode project

Sorry for repeating a question albeit slightly differently but I've tried everything, searched this forum and google but can't solve this issue. I have a Sqlite database (only 20kb size) which I want to use in a Swift 4 project using Xcode. I've put the database (a .db file) in the folder where Xcode saved my project but when I run the app I get the 'no such table error'. Following the file path in the debug screen takes me to a file of 0kb i.e. empty. I thought I'd solved this by using the path name (i.e. FileManager.default.fileExists(atPath: "/Users/...") but it won't work on my iPhone (only in Simulator) so I've gone back to trying to use the URL approach. I've copied the main bit of code but my suspicion is that there is something either wrong with the first few lines or I haven't filed the .db file in the right place. I have added it to the project inspector, it is associated with the project as the target and it shows under the copy bundle resource bit of the build phases screen. I'm really struggling here so any help really appreciated.

//Function to open Cities database, add cities to array, sort alphabetically and then append "Please select city" at the start of the array
func populatePickerView() {
    let fileURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
    let databaseURL = fileURL.appendingPathComponent("Wanderer.db")
    let database = FMDatabase(path: databaseURL.absoluteString)

    guard database.open() else {
        print("Unable to open database")
        return
    }

    do {
        let cities:FMResultSet = try database.executeQuery("SELECT City from Cities", values: nil)

        while cities.next() {
            if let result = cities.string(forColumn: "City") {
                cityData.append(result)
            }
        }
    } catch {
        print("OOPS, some sort of failure")
    }

    cityData = cityData.sorted(by: <)
    cityData.insert("Please select city", at: 0)
}
like image 840
RobM Avatar asked Oct 30 '18 22:10

RobM


People also ask

How do I see SQLite database in Xcode?

Open finder press Command+g "~/Library/Application Support/iPhone Simulator" then go. Save this answer. Show activity on this post. Open Finder, press Shift + Command + G, paste the path and press Go.

Where do I find my SQLite database?

The Android SDK provides dedicated APIs that allow developers to use SQLite databases in their applications. The SQLite files are generally stored on the internal storage under /data/data/<packageName>/databases.

Where is my SQLite database file Mac?

SQLite is included in macOS and Mac OS X by default. It is located in the /usr/bin directory and called sqlite3. Using SQLite, users can create file-based databases that can be transported across machines, platforms, etc.

Where is SQLite database stored iOS?

The database that can be used by apps in iOS (and also used by iOS) is called SQLite, and it's a relational database. It is contained in a C-library that is embedded to the app that is about to use it. Note that it does not consist of a separate service or daemon running on the background and attached to the app.


1 Answers

If you drag and dropped your database to your Xcode project structure with "copy items if needed" and your target selected, your database is located here:

let databaseInMainBundleURL = Bundle.main.resourceURL?.appendingPathComponent("Wanderer.db")

If you just want to read the data this will be fine, because the main bundle is read only.

If you want to save something in your database you need to copy the data base to the documents directory.

You can use this function to check if your database exists in document directory and copy if needed.

func copyDatabaseIfNeeded(_ database: String) {

    let fileManager = FileManager.default

    let documentsUrl = fileManager.urls(for: .documentDirectory, in: .userDomainMask)

    guard documentsUrl.count != 0 else {
        return
    }

    let finalDatabaseURL = documentsUrl.first!.appendingPathComponent("\(database).db")

    if !( (try? finalDatabaseURL.checkResourceIsReachable()) ?? false) {
        print("DB does not exist in documents folder")

        let databaseInMainBundleURL = Bundle.main.resourceURL?.appendingPathComponent("\(database).db")

        do {
            try fileManager.copyItem(atPath: (databaseInMainBundleURL?.path)!, toPath: finalDatabaseURL.path)
        } catch let error as NSError {
            print("Couldn't copy file to final location! Error:\(error.description)")
        }

    } else {
        print("Database file found at path: \(finalDatabaseURL.path)")
    }
}

and use with:

copyDatabaseIfNeeded("Wanderer")

After that you will be able to use your populatePickerView function.

like image 63
Retterdesdialogs Avatar answered Sep 26 '22 00:09

Retterdesdialogs