0

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)

2
  • Where is your database file located? Bundle and container are different places. Commented Nov 7, 2020 at 4:52
  • @Asperi I've integrated the database file into to project such that its location in my computer is /Users/diego/Desktop/Bites/Bites/Database Commented Nov 7, 2020 at 21:25

1 Answer 1

2

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
Sign up to request clarification or add additional context in comments.

21 Comments

How can I do this?
What do you mean? Just don't save the path. To get the documents directory url let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! to construct your fileURL let fileURL = documentDirectory.appendingPathComponent("yourFile.ext")
I tried using this code but it said it couldn't find the table in the database after creating the connection, which means it couldn't find the database and it created a new one instead. I checked what fileURL returns and it said expression produced error: error: /var/folders/1f/102gzjts5p96d2_mzkyx27dh0000gn/T/expr5-d55158..swift:1:65: error: cannot find type 'Foundation' in scope Swift._DebuggerSupport.stringForPrintObject(Swift.UnsafePointer<Foundation.URL>(bitPattern: 0x10f8676b0)!.pointee)
Can you edit your question and post your code? Where is your database located?
I wont ask if you did import Foundation because NSSearchPathForDirectoriesInDomains is working
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.