Sandboxing issue : sandbox and SQLite Database

Hi there,

I’m facing a new problem. When I prepare my app for the appStore with AppWrapper Mini, I check the sandboxing option and when I build my application, I can’t create a new DatabaseFile…

I believe it’s a problem of rights cause if I uncheck this option of sandboxing, there is no issue any more.

App should be sandboxed before to be published on the AppStore, so, what can I do to allow users to save a file somewhere in the computer?

Thank you for your help!

Sandboxing limits where and how things can be saved. Where are you trying to save?

  • If you prompt the user to choose the file and location, it can be saved at the location they chose, assuming write-access of course.
  • If you are saving stuff behind the scenes, then you need to use SpecialFolder.ApplicationData.

As a user, I’m trying to save on my desktop but not allowed. In my Documents but also not allowed. However I choose the location where I want to save my file through a SaveAsDialog.

I think the user should be able to save wherever he wants to if the app allows him to choose a location, even if the app is sandboxed…?

If this screen capture can help…

Make sure that you’re building a Cocoa application, otherwise your AWM settings look fine to me.

The other thing is that you must use the folderitem returned from the SaveAsDialog, you cannot modify it any way (like add a file extension or change the name).

I’m using the cocoa framework to build my application.

Here is my code :

[code] dim f As FolderItem
dim o As SaveAsDialog

o = new SaveAsDialog
o.PromptText = “New document”
o.SuggestedFileName = “My file.acs”
o.Filter = FileTypeDS.MyFileType

f = o.ShowModal

if(f<>nil) then
dim db As New SQLiteDatabase
db.databaseFile = f
db.databaseFile.ExtensionVisible = true

if(db.createDatabaseFile) then
// Go on
end if
end if
[/code]

I just tried your code and it works in a demo application here.

Two questions.
#1 Does your project have a “Bundle Identifier”?
#2 Does your file type have the file extension specified?

#1 Yes
#2 Yes

In fact, the file is created but is empty, I can’t write my database inside…

if(db.createDatabaseFile) then // Go on createTables() end if

My function createTables doesn’t work. I get the error 1 - Operation cannot be completed because the database is closed (Ref : Post on Database File Creation )

Oh - I haven’t done any database work in years, so this is beyond me at this point. Hopefully someone with DB experience can assist you with this. However using AWM, our apps include AWM work in a Sandboxed environment. Although our data files are either flat text/binary or document packages (which are folders).

If your database file is created in your sandbox environment, it means that your sandbox is working fine. Just based on your codes above and your error description, it looks like you never actually “connected” to your database. I think that is the issue you are having, not the sandbox. I don’t have access to the rest of your database setup code, but

Operation cannot be completed because the database is closed

usually means what it says… you are not connected. Try adding this if you have not already done so (once you verified that your database file exists):

if(db.createDatabaseFile) then

    if db.connect = false then
      // Connection to database failed, handle error
   else
     // We have a connection, go on and create the table.
     createTables()
   end if

end if

Please note, you should also check to see if the table(s) are missing or have yet not been created before running createTables().

[quote=32642:@SbastienAngot]In fact, the file is created but is empty, I can’t write my database inside…

if(db.createDatabaseFile) then // Go on createTables() end if

My function createTables doesn’t work. I get the error 1 - Operation cannot be completed because the database is closed (Ref : Post on Database File Creation )[/quote]
If you’re using the SQLiteDatabase.CreateDatabaseFile method then it should not only create the database file but also connect to it. As Nona suggested, providing more of your database related code would make it easier for us to help you.

This morning (actually it’s the afternoon as I overslept), I recall that there is something you need to do with that database when using it the way you do. I can’t recall exactly and haven’t been able to find it, but it’s to do with the database creating a temporary file when you write to it, and this option needs to be turned off.

Try sending Bob Keeney a message as he’s probably one of the most knowledgable guys I know on databases.

Ok, I’m gonna try to give you a more complete code :slight_smile:

[code]
function createNewDoc()
{
dim f As FolderItem
dim o As SaveAsDialog

o = new SaveAsDialog
o.PromptText = “New document”
o.SuggestedFileName = “My file.acs”
o.Filter = FileTypeDS.MyFileType

f = o.ShowModal

if(f<>nil and createDatabase(f)) then
// Go on with the created file
end if
}

function createDatabase(f As FolderItem)
{
db = new SQLiteDatabase

db.databaseFile = f
db.DatabaseFile.ExtensionVisible = true
db.EncryptionKey = encryptionKey

if( db.CreateDatabaseFile and db.Connect ) then
db.SQLExecute(“MY SQL REQUEST”)
db.Close
return true

else
Return false
end if
}[/code]

this following code line get the error 1 : Operation cannot be completed because the database is closed

db.databaseFile = f  

and this one get the error 14 : unable to open database file

db.SQLExecute("MY SQL REQUEST")

Hope my code can be helpful!

I had the same problem with my app. After I have changed the database location to “SpecialFolder.ApplicationData”, I can create the database file and fill it with some tables and data.
I think the problem is, that the creation of the database file runs with the open/save dialog in the sandbox, but your connect request runs without a sandbox open/save dialog. I you would have access a exisiting database outside the sandbox folders, so you must open it everytime with the save/open dialog.

What? Kidding right?
My app uses SQLite database files created and opened by the user that is written to many times after it’s been created/opened.
I will run into this issue when sandboxing my app then…? Great :confused:

I would suggest that you force the user to use the SpecialFolder.ApplicationData folder. He can still choose a filename that he likes, just not where he can place the file.

[quote=32842:@Albin Kiland]What? Kidding right?
My app uses SQLite database files created and opened by the user that is written to many times after it’s been created/opened.
I will run into this issue when sandboxing my app then…? Great :/[/quote]
Not exactly. The app needs to use a dialog to obtain initial permission to the FolderItem, yes. But while you have permission, you can create and store a Security Scoped Bookmark to obtain permission on subsequent launches. This is very similar to GetSaveInfo with one major exception: you must explicitly “start” and “stop” the access rights. Meaning, start before you connect, stop when you’re done. MacOSLib makes it quite painless though.

[quote=32810:@Sam Rowlands]This morning (actually it’s the afternoon as I overslept), I recall that there is something you need to do with that database when using it the way you do. I can’t recall exactly and haven’t been able to find it, but it’s to do with the database creating a temporary file when you write to it, and this option needs to be turned off.

Try sending Bob Keeney a message as he’s probably one of the most knowledgable guys I know on databases.[/quote]
That sounds like Write Ahead Logging, but I’m not certain.

Thanx Thom, always helpful :slight_smile:
I’ll look into that when my enrollment is approved and I have my certificate for sandboxing!

So… If I understand, if I want to create a databaseFile I need to use the folder “SpecialFolder.ApplicationData” ? So the user can’t really choose to save the file in his Documents?!? It’s weird and not convenient…

I don’t understand the fact that the user can choose where to save the file, the file is created with no data inside, and when I want to put into a database that doesn’t work… Is it a problem from XOJO?