User is having trouble reading preferences files

That is very helpful. The user having problems is very interested in getting this problem solved, so I will probably send him some versions that have more helpful “else” msgboxes that might give me a clue what’s going on. Right now it only gives a generic message that it could not be opened, to prevent a crash. Perhaps I could work in what the permissions are into the msgbox.

1 Like

I made the user a test app that told me permissions for the 3 files my app accesses, 2 in the ~/Library/Application Support/MyApp folder and 1 in the ~/Library/Preferences folder. The 2 in the Application Support folder are both readable and writable and set to 420. The one in the ~/Library/Preferences folder is set to 384 on his computer. Why would that be different than my computer? Would manually changing it via the s/w to 420 fix it? I’m not sure what 384 translates to as far as the Read & Write permissions displayed in the Get Info window.

420 decimal (I assume) is 644 octal, which is read/write for owner, read only for everyone else.

384 decimal is 600 octal, which is read/write for owner, no access for everyone else.

So it would make no difference in the s/w reading and writing the file.

No. Same rules for everybody. As long as the file’s Owner is your client, it’s good. If not, that could explain the error.

1 Like

Software wise, Xojo isn’t always accurate with isReadable and isWritable.

2 Likes

Also, I’m assuming .Exists is true. Otherwise, you’re probably just getting the user defaults. What would be applied if the file were created.

1 Like

I’ve been working with this user. We’ve eliminated the getPrefs method as the cause. It seems to be when the savePrefs method is called, it crashes with an iOExceptionError number 104. Does this mean the file is busy? or if not, then what?

Here is the code for that method:

dim f as folderItem
dim t as textoutputStream
dim txtFont, txtSize,  txtStyle, txtColor as string

txtFont= str(prefsWin.fontPopup.listIndex)
txtSize= prefsWin.fontSize.text
txtStyle= str(prefsWin.fontStyle.listIndex)
txtColor= str(prefsWin.fontColor.listIndex)

f = specialFolder.ApplicationData.child("MyApp").child("MyAppPreferences")

if f <> nil then
  
// Seems to crash here with no msgBox 
  t = TextOutputStream.create(f)


   if t <> nil then
   
    t.writeLine txtFont
    t.writeLine txtSize
    t.writeLine txtStyle
    t.writeLine txtColor

    t.close
       
  else 
    // alert he should have gotten before it crashed...
    msgBox "MyAppPreferences file could not be created."
end if

else
  msgBox "MyAppPreferences file could not be opened in order to write to it."
end if

perhaps


f = specialFolder.ApplicationData.child("MyApp").child("MyAppPreferences")

if f<> nil and f.exists then
try
f.delete
catch
msgBox "MyAppPreferences file could not be deleted"
end try
end if

if f <> nil then
1 Like

If the file is “in use”, though, would I be able to delete it?

I checked my getPrefs method and I do have a t.close at the end of that method, so it shouldn’t still be open from that.

I also just found this similar thread from 2018, but there didn’t seem to be a resolution posted.

Depends what is ‘using’ it.
I find odd effects on some customer Mac devices where iCloud or dropbox is monitoring a folder.

delete a file, check it exists, and it is ‘still there’ for a short while.
create a file, check it exists and it is ‘not there’ for a short while.
Sometimes waiting for 0.5 to 1 second before testing is enough to resolve the issue.

I’m convinced it is ‘while stuff is moved up/down from the internet’ or having a status changed.
Virus checkers on Windows can grab a file temporarily.

getPrefs method and I do have a t.close

Is there any error trapping that might cause the t.close to be skipped?
Such as an exception at the end of the method, or an ‘unhandled exception’ handler.
So that


t = textstream.create(blah)
dostuff
dostuff2
dostuff3   // causes an error
t.close

exception
//if it bounces to this point, the stream isnt closed
1 Like

The Finally clause exists exactly for that

Try
  openThing()
  Try
     proc1()
     proc2()
   Catch processError
     // something failed processing
   Finally
     closeThing()
   End
Catch openError
  // failed to open
End
2 Likes

Don’t know if this will help, but personally I would concatenate these strings into a single string (called “Bob” here), adding an EndOfLine or other separator to each. Then we would do a single t.Write Bob.

1 Like

i tried adding

app.DoEvents(500)

in case it needed more time, but it still crashed for him with the IOException 104 again. I’ll try some of the other suggestions next.

Ouch! Not a good idea.

Independent of the fact that the code crashes the code is really suboptimal:

  • declaring of the variables at the start of the code
  • the naming of the variables
  • hard coding the variables to the preferences file
  • how the file is written

The preferences should be decoupled from the interface. The file format should not depend on the order of the values.

I don’t think this helps much, as part of my now discontinued app kit, I wrote a function to resolve the IOException error codes.

Code 104 returns "State not recoverable".

What this means, your guess is as good as mine, it might very well indicate an APFS corruption, you’d have to check APFS – The Eclectic Light Company for more information on APFS and it’s problems.

Makes me wonder if the user needs to repair the disk permissions, but then I believe he tried to install on other machines and had the same trouble, so maybe that’s not the case. I guess it couldn’t hurt to try.

The OS (Ventura) issue a permission dialog; if your user click in deny…

NB: I even saw Windows 10 warning for permissions using a dialog box…

User is on Monterey.

I remember seeing a dialog box when installing the app that it wanted permission to access my Downloads folder on Ventura, but i don’t remember anything else after that when actually using it. I’m betting all would be corrected if he upgraded to Ventura. Maybe repairing permissions might help too.

The problem with people (Xojo developers included) is…

they lie,
they forget to tell things (skip important parts),
they click in Don’t and forget to tell,
they fear to click in OK (and forget to tell)…

etc.

The file I want to access is in my Documents folder.
I am asked by the OS at read time for the List window, then when I want to display the Record in the Record view window, I am asked one more time. (then I can navigate inside the sqlite db file).