FREE TRIAL: Accelerate your app development career with Hacking with Swift+! >>

SOLVED: how do you deploy a sqlite database with your app

Forums > macOS

I have a local sqlite database that I am accessing with no problems. I can create an archive with the database in the bundle, and copy and access it to various places. I check if the file exists, if is does not, I copy it from the bundle and open it with no problems This works fine running from Xcode

let fileURL = try! FileManager.default
            .url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
            .appendingPathComponent(dbName)
if sqlite3_open_v2(fileURL.path, &db, SQLITE_OPEN_READWRITE, nil) == SQLITE_OK {
            print(fileURL.path)
            return
        }

Now I archive the app and Copy App

I then copy the app to a usb drive

execute the app and it creates the file in the same place and runs fine.

Now...How do I take this to someone elses machine and run since my user will not be on their machine.

I have messed with other locations, and it is just like being back on Unix, all your problems have to do with permissions.

What is the standards for doing this? I am at my witts end:-(

   

Your code doesnt say much except that you are looking the database in the documents folder. Where do you do the copy?

Is the app sandboxed?

   

So I deleted the App Sandbox from the Signing&Capabilites

Then I created a Directory right off my User and made sure I had read/write permissions and everything is fine.

I have been totally paranoid about removing the sandbox...what else does that open?

just an FYI, this is the code that I finally got going to do the initial copy if the database is not there.

        let fileURL = FileManager.default.homeDirectoryForCurrentUser
            .appendingPathComponent("HandicappUI")
            .appendingPathComponent(dbName)

        // see if db is in app support directory already
        if sqlite3_open_v2(fileURL.path, &db, SQLITE_OPEN_READWRITE, nil) == SQLITE_OK {
                    print(fileURL.path)
                    return
                }
        // clean up before proceeding
        sqlite3_close(db)
        db = nil
                // if not, get URL from bundle
        guard let bundleURL =  Bundle.main.url(forResource: "HandiCap", withExtension: "sqlite") else {
            print("db not found in bundle")
            return
        }

        // copy from bundle to app support directory
        do {
            try FileManager.default.copyItem(at: bundleURL, to: fileURL)
        } catch {
            print("unable to copy db", error.localizedDescription)
            return
        }

        // now open database again
        guard sqlite3_open_v2(fileURL.path, &db, SQLITE_OPEN_READWRITE, nil) == SQLITE_OK else {
            print("error opening database", errorMessage())
            sqlite3_close(db)
            db = nil
            return
        }

        // report success
        print("db copied and opened ok")
        return

   

If the app is sandboxed, then you can write to your own container's documents directory (which is very hidden from the user). If you want to write to the user's documents directory, then you need to pop up an open dialog and ask the user to select the directory first. Then your app will have permission.

Alternatively, turn off sandboxing, but then you can't be in the Mac AppStore.

   

There is still an issue in that code I think. It depends on the fileURL container directory being there when you copy, it needs the HandicappUI in a folder in the home directory. It doesnt look like you are creating it.

Style wise you are calling similar code twice to test for the SQLite connection, also consider just testing for the existance of the file at this stage as it may be faster.

If you were to go back to the sandboxed application then the code should work if you create a directory in the sandboxed documents folder.

   

This is the code I did to get this working.

The actual implementation only gets done if the open of the data base fails. That "should only happen" on the first execution of the app. so the file can get created from the bundle. And yes, I create the directory if it is not there.

The nice thing about the sandboxing is that this is for me alone. I do this app over and over again to learn a new language. This is the 5th implementation over the years.

   

Hacking with Swift is sponsored by Sentry

SPONSORED With Sentry’s error and performance monitoring for iOS you see mobile vitals that actually matter, can solve any latency issues quickly, and learn how each release is performing over time.

Get started

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.