deyles-zz / sculejs

SculeJS - data structures for the web
165 stars 24 forks source link

You don’t have permission to save the file “xxx.json” in the folder “Documents” #54

Closed john-dalsgaard closed 8 years ago

john-dalsgaard commented 9 years ago

In an app running on iOS (iOS9.1) created using Appcelerator Studio I use SculeJS as the underlying database. The app is used to register user's fishing trips - and keeps a "duration" updated for the current trip. And while testing this on a device (iPhone 6) I have started seeing this on the console of Studio:

Could not write data to file at path "/var/mobile/Containers/Data/Application/F1550224-D890-4FC6-B814-3518BF789B9B/Documents/currentTrip.json" - details: Error Domain=NSCocoaErrorDomain Code=513 "You don’t have permission to save the file “currentTrip.json” in the folder “Documents”." UserInfo={NSFilePath=/var/mobile/Containers/Data/Application/F1550224-D890-4FC6-B814-3518BF789B9B/Documents/currentTrip.json, NSUserStringVariant=Folder, NSUnderlyingError=0x164af7b60 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}}

I guess that it is related to the app "going in the background" - but so far just a pure guess.

I have tried to search for the error (and parts of it) - but so far has found no explanation - let alone an idea of how to fix this???

This is getting a little critical as the app is going to be released soon (this is actually the final tests). So any ideas as to why this occurs and what I can do about it would be greatly appreciated!

/John

deyles-zz commented 9 years ago

Heya John,

Which version of the Titanium SDK are you using to build your app? SculeJS allows you to specify a path when saving your database files, defaulting to the value of Titanium.Filesystem.applicationDataDirectory if none is provided.

I suspect your issue has to do with the following code in SculeJS (https://github.com/dan-eyles/sculejs/blob/master/lib/com.scule.js#L5109):

var file = Titanium.Filesystem.getFile(this.configuration.path, tmpPath);
file.write(JSON.stringify(object));
file.rename(realPath);

Off the top of my head I'd try the following things:

john-dalsgaard commented 9 years ago

Hey Dan

Thanks for the quick response.

I am using the newest version of Appcelerator Studio (4.3.3.201510212245) and the SDK (5.0.2.GA).

As part of the test I have actually removed the application (which I believe also removes all of the files) recently before I saw the error. And it is not a consistent error... It saves lots of data - only throws this error now and then. As I mentioned I think it may be related to the app going "in the background" - while running a timer that will try to write when it is triggered. So as far as I can see the path in the error message seems Ok (i.e. in "..../Documents" and named "collection".json).

I'll try to see if I can narrow it further down...

/John

From: dan-eyles notifications@github.com To: dan-eyles/sculejs sculejs@noreply.github.com Cc: John Dalsgaard john@dalsgaard-data.dk Date: 16-11-2015 11:12 Subject: Re: [sculejs] You don’t have permission to save the file “xxx.json” in the folder “Documents” (#54)

Heya John, Which version of the Titanium SDK are you using to build your app. SculeJS allows you to specify a path when saving your database files, defaulting to the value of Titanium.Filesystem.applicationDataDirectory if none is provided. I suspect your issue has to do with the following code in SculeJS ( https://github.com/dan-eyles/sculejs/blob/master/lib/com.scule.js#L5109): var file = Titanium.Filesystem.getFile(this.configuration.path, tmpPath); file.write(JSON.stringify(object)); file.rename(realPath); Off the top of my head I'd try the following things: Remove the application from your device, clear all files, and install again Try using a different filename Specify the library directory path of the application rather than using the data directory — Reply to this email directly or view it on GitHub.

john-dalsgaard commented 9 years ago

Ok, it took me a while to re-produce the error.... I re-created the app and deployed it (with some further logging) - and it seems that the error occurs when I move away from the part of the app that contains the "currentTrip" (as in the error message) - so I guess it has to do with perhaps some variables (e.g. the with a reference to the collection in SculeJS) that goes out of scope... If that is the reason then I should be able to handle it e.g. by re-requiring the collection. I'll let you know if I learn more - and cannot handle it in my own code ;-)

deyles-zz commented 9 years ago

Hey John,

That might explain it, you may also see an error if you attempt to write to a file that another process has an active handle on (i.e. you open the collection twice, or have multiple execution contexts).

I'd implement a module that acts as a singleton container for collections, that would mean your collections never get garbage collected and you won't need to open collections in various locations in your program.

john-dalsgaard commented 9 years ago

Hey Dan

Well, that is actually what I do - but I think I have stumbled across a small glitch in that I can end up having collected a temp. variable that is used by the function triggered by the timer. So not really obvious - but I have a clue now ;-)

Thanks!

/John

john-dalsgaard commented 8 years ago

I have not seen the problem since I changed it to directly use require('...') to get my collection.

So I'll close this issue :-)