I'm attempting to open an SQLite3 database in my SwiftUI code, to access the file path within the bundle, I'm using the following function;
let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
.first!
However I keep getting the error unable to open database file (code: 14)
, but after trying to run it a few times I realized that the second last folder from path
is different every time I run the code. How can I find a path to the bundle that will not change so the code works?
These are some examples of how the path changes:
Second last folder is named: CAC91DB3-E264-436F-89A8-1E3D76C4DC56
/Library/Developer/CoreSimulator/Devices/EFD14A1B-7207-4840-9ACE-8E44A269CC70/data/Containers/Data/Application/CAC91DB3-E264-436F-89A8-1E3D76C4DC56/Documents
Second last folder is named: 0A23051F-9362-4B4D-B49B-BE0F028384DC
/Library/Developer/CoreSimulator/Devices/EFD14A1B-7207-4840-9ACE-8E44A269CC70/data/Containers/Data/Application/0A23051F-9362-4B4D-B49B-BE0F028384DC/Documents
Edit: This is the code that I am using:
Import swiftUI
Import Foundation
Import SQLite
func openDatabase() {
let ProductID = Expression<Int64>("ProductID")
let Name = Expression<String>("Name")
let Calories = Expression<Double>("Calories")
let Protein = Expression<Double>("Protein")
let Carbs = Expression<Double>("Carbs")
let Fats = Expression<Double>("Fats")
let Weight = Expression<Double>("Weight")
let Category = Expression<String>("Category")
let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let fileURL = documentDirectory.appendingPathComponent("Database.db")
let db = try! Connection("\(fileURL)")
let Products = Table("Products")
//Thread 1: Fatal error: 'try!' expression unexpectedly raised an error: no such table: Products (code: 1)
for prID in try! db.prepare(Products) {
print("productid: \(prID[ProductID]), name: \(prID[Name]), calories: \(prID[Calories]), protein: \(prID[Protein]), carbs: \(prID[Carbs]), fats: \(prID[Fats]), weight: \(prID[Weight]), category: \(prID[Category])")
DatabaseTest().dataTest.append(Product(name: prID[Name], calories: prID[Calories], protein: prID[Protein], carbs: prID[Carbs], fats: prID[Fats], weight: prID[Weight]))
}
}
For clarification on sqlite.swift
reference:
(https://github.com/stephencelis/SQLite.swift/blob/master/Documentation/Index.md)
This is because all applications in iOS are sandboxed. There is no way to avoid that. You can not save the full path. It will change every time you launch your App. What you need is to save only your file name and its parent directory. Use them to contruct a new fileURL and/or path every time you need to access them.
edit/update:
If your file is located inside your App Bundle:
let databaseURL = Bundle.main.url(forResource: "Database", withExtension: "db")!
Note: If you need the database path you have to get your fileURL path property not the absoluteString. Last but not least the Bundle is read only. You need to move/copy your database to another directory (application support) to be able to modify it.
let databasePath = databaseURL.path