Did Managing Text Files Change for Silicon?

I built an app using the old Intel processor and 32 bit architecture which I’m trying to update to run on the new 64 bit architecture but my code for reading and writing text files no longer works. Here’s my code which ran perfectly before:

All it’s supposed to do is look for a folder in the Documents folder and if it’s not there, create one.

Thanks!

You are aware that you are actually NOT saying what the error is that you are getting???

Have you looked at the debugger info? What does it say?

And please don’t post screenshots of code - just post the code and wrap it in code tags. Then people can quickly copy it for testing. Or better provide a sample project.

But I would guess cbFile is Nil - and you do not test for that as you should.

Sample code from the docs:

Var f As FolderItem = FolderItem.ShowSaveFileDialog(FileTypes1.Text, "Create Example.txt")
If f <> Nil Then
  Try
    Var t As TextOutputStream = TextOutputStream.Create(f)
    t.WriteLine(TextField1.Value)
    t.Close
  Catch e As IOException
    // handle error
  End Try
End If

Note that there is a difference between being Nil (the variable) and exists (on disk)

2 Likes

Thanks for the reply, Markus, and sorry for not posting the error. Sometimes I try to over simplify things. Anyway, it’s throwing a NilObjectException. And you’re correct, the debugger says cbFile is Nil along with other variables that were never Nil on the old machines. The question is, why are these variables suddenly Nil on the new machines?

Anyways, I was just curious if perhaps Xojo changed something in the way Folder Items are handled on the new architecture. It sounds like it hasn’t and I just need to do more investigating. Thanks again for your help, sir!

Big Sur do not ask you for permissions ?

1 Like

Have you checked that you have the folder and file in question? Maybe you named the folders differently, eg “Vocabulary files” instead of “Vocabulary_files”?

If you do, then as Emile says it might be a permission problem.

1 Like
  1. Does the folder 'Vocabulary_Files" exist in the users Documents folder? Do you have code to create it if it doesn’t? If so, I would recommend adding code to verify that the folder creation was successful.

  2. As @Emile_Schwarz says, Apple has gotten really protective of certain files and folders, for your own safety, security and safety. If your application is not code signed, and doesn’t have the “Privacy Usage” string for accessing the documents folder, your app probably is blocked from doing so. Use App Wrapper to sign your application (read up on how to add a Xojo script to your project so that debug builds are signed), and on the Capabilities pane, fill out the “Privacy Usage” message next to “Documents Folder” under the “Files & Folders” heading.

This will cause a “Permissions” dialog to appear when the app tries to access the Documents folder, be warned the customer can “Deny” the permission and there’s nothing you can do about it. So you must consider a backup plan, when this happens.

  1. If you don’t want to do number 2, you should be able to get around it by using a selectFolderDialog to ask the customer where to save their files on the first launch of your application. If you’re not going into the App Store, you simply store this path in the application preferences. This should be sufficient, however If you’re going into the App Store, well that’s a whole different kettle of fish, and you may want to seriously consider determining if the App Store hoops are going to be worthwhile.

Yes, that code is there. The app is written so that when it’s used on a new machine for the first time, it will create the “Vocabulary_Files” folder and then create a “Chapters and Books” text file inside the “Vocabulary_Files” folder. The code that did this was:

Dim cbFile As FolderItem = SpecialFolder.Documents.Child("Vocabulary_Files").Child("Chapters and Books")

Dim cBOutput As TextOutputStream
If Not cbFile.Exists Then
  cBOutput = TextOutputStream.Create(cbFile)
  cBOutput.WriteLine(chapterBook.Text)
  cBOutput.Close
  SelectVocabulary.AddRow(chapterBook.Text)
  chapterBook.Enabled = false
End If

But apparently, that method for creating a folder and a file inside the folder doesn’t work anymore. I know it worked in 2018 because the app performed flawlessly for the year or so that I used it. Now you’'re probably thinking that the app worked because there was always a “Vocabulary_Files” folder in the Documents folder. But if that were the case, then putting one there should solve the problem but it doesn’t. In fact, it aggravates the problem. The “Vocabulary_Files” folder contains text files that store data which is loaded each time the app launches (It’s basically a data base). But now, if the app sees that the folder already exists, it fails to even launch! So if the folder isn’t there, the app will launch but crashes as soon as the code above executes. And if the folder is not there, the app won’t launch at all.

So my thanks to everyone who tried to help out, but the only thing to do at this point is just rewrite that part of the code. But this is about the weirdest thing I’ve ever seen as a developer.

All the projects I moved to M1 (created with 2015r1) works fine running in the IDE with 2021r2…

I don’t doubt what you’re saying at all, Emile, but unless gremlins snuck in and altered my original code, something changed along the way. Another thing I discovered is that if you run the previous IDE on the new M1 MacBooks, the MessageBox function doesn’t work.

Isn’t this API2 ?

I was talking about far before API2.

Now, I do not know if in these projects I use text files in the way you do (or text files at all).

MsgBox contents appears centered and eventually with a vertical ScroollBar is the contents is taller than the screen !

I checked a project that wrote Preferences file as text and it works fine. I save and Open Colors, Integer (as text and converted), Font Size (as text and converted) and at last a simple string (few characters, probably less than 20 characters).

Original project written using 2015r1, nothing fancy, no plugin, nothing.

Take code from the LR and then try to write / read text.

I originally wrote the app using 2017r3. And all I know is that it ran perfectly several years ago, and today was the first time I even touched the project since I first created it. Frustratingly, I have no explanation for why it’s no longer working. But regardless of what broke, I know I can fix it so I’m not gonna stress out over it.

Thanks so much for your input, Emile!

The IOException is actually telling you that you’re trying to create a file in a non-existent path. The following works:

Dim cbFile As FolderItem = SpecialFolder.Documents.Child("Vocabulary_Files")
if cbFile.Exists = false then cbFile.CreateFolder

cbFile = cbFile.Child("Chapters and Books")
If cbFile.Exists = false Then
  Dim cBOutput as TextOutputStream = TextOutputStream.Create(cbFile)
  cBOutput.WriteLine("Test")
  cBOutput.Close
End If

Note that it’s an IOException#2, not a NilObjectException, that I’m seeing.

All of this is likely the result of the framework changes a few releases back for FolderItem et al to support recent macOS versions. What used to work no longer works, and probably shouldn’t have worked to begin with.

Thanks, Anthony! That was my first inclination as well. As I was telling Emile, unless gremlins came in and rewrote my code, something had to have changed on either Apple’s end, Xojo’s end, or both.

It’s true, that bit of code there was throwing an IOException, but there must be something else upstream from that that was causing it to crash from an unhandled NilObjectException. I haven’t really looked at everything closely yet. Anyways, today I begin the task of fixing all the new problems, and the code you provided gives me a nice head start.

Thanks again, sir!

1 Like

Happy to help. Don’t forget to mark a solution so that others who might stumble across this in the future can easily find the answer.

1 Like

Don’t “for_get”, as already has been written above, now the user must confirm your access to the Documents folder.
Maybe consider to use your Application Support subfolder now, instead of.

1 Like

Excellent reminder as I probably would have forgotten about that (I actually did forget). However, I’m currently working on an iOS version and in two weeks, I’m meeting with a potential client who wants to see everything the iOS version will eventually do. And I’m only using the current version to demonstrate its full functionality. Consequently, the ‘text files for database’ thing only needs to work until then. After that, I’ll be implementing an actual database which is really what I should have done in the first place.