Skip to main content
Known Participant
July 22, 2014
Answered

iOS 8 - FileStream throwing error 2038 on open for write?

  • July 22, 2014
  • 2 replies
  • 6826 views

Hey all,

Going through iOS 8 compatibility checks with our Adobe AIR app (tested with AIR 13 and AIR 14), I'm noticing changes to file storage.

In short, my code has always been as follows for simply storing a player profile file (matching iOS documentation for as fas as I know: File System Programming Guide: File System Basics). And this has worked well to prevent purges when the device is low on storage space as well as keeping the data there when updating the app.

This code only seems to work for iOS 4 to iOS 7:

var storagePath:File = new File(File.applicationDirectory.nativePath + "/\.\./Documents");

try

{

     var targetFile:File = storagePath.resolvePath("profile.bin");

     var stream:FileStream = new FileStream();

     stream.open(targetFile, FileMode.WRITE);

     stream.writeBytes(<byteArray here>, 0, 0);

     stream.close();

}

catch (err:Error)

{

     <informs user something went wrong, retries, etc. basic error handling>

}

Running this on iOS 8 will always throw a SecurityError (#2038) from stream.open.

Now, we can still save data and fix this by replacing the first line by:

var storagePath:File = new File(File.applicationStorageDirectory.nativePath);

But, this leaves me with a few things, in order of descending importance:

1) Reading something like this makes me scared as our game has a large amount of daily players: "I’m using applicationStorageDirectory to store files. The problem is those files get deleted when the user updates his app…" (AIR App Compliance with Apple Data Storage Guidelines, last comment)

2) What has changed in the iOS 8 file system that suddenly makes my original code fail? Apple developer documentation is still outlining this should be valid. Is this a possible AIR bug?

3) I assume I need to set "don't backup" flags on the files when saving to the appStorageDir?

4) Is anyone else running into this?

Thanks in advance!

This topic has been closed for replies.
Correct answer jadams602

Does it make a difference if you replace:

var storagePath:File = new File(File.applicationDirectory.nativePath + "/\.\./Documents"); 

with:

var storagePath:File =  File.documentsDirectory;

??

You should really be using File.documentsDirectory and not that assumption about walking up from a relative path from File.applicationDirectory anyway.

2 replies

unutoiul74955614
Participant
April 9, 2015

Hi Guys,

I have an AIR game that's is loading the data from some json files, like current_score.json.

When i'm compiling using AIR 15.0.0 on IOS8 device i can find my file only using  File.applicationDirectory and is siting at private/var/mobile/Containers/....

Because is siting on private in IOS8 I can't override or update it file as I don't have permission in IOS8.

My questions are:

1. File.documentsDirector,  File.applicationStorageDirectory or File.userDirectory is not finding my current_score.json file, it should find it?

2. When I install the app the assets files like(.json) files will be copied in

/var/mobile/Containers/Data/Application/713F4EEA-8502-40F6-AA49-B2812E5206F2/Documents

?


3.If not, how can I use this file? do I need to make a copy of it all the time when I start the app? or how this is going to work?


Thanks,

Lucas



jadams602
jadams602Correct answer
Inspiring
July 22, 2014

Does it make a difference if you replace:

var storagePath:File = new File(File.applicationDirectory.nativePath + "/\.\./Documents"); 

with:

var storagePath:File =  File.documentsDirectory;

??

You should really be using File.documentsDirectory and not that assumption about walking up from a relative path from File.applicationDirectory anyway.

Known Participant
July 22, 2014

Thanks for your quick reply!

I agree about not traversing up the directory tree, but a blog post from an Adobe employee I read a long time ago put me on that track: Saumitra Bhave: AIR iOS- Solving [Apps must follow the iOS Data Storage Guidelines]

Anyway, I ran some tests including your suggested solution and it returns an interesting result:

#1 File.documentsDirectory (iOS 8)

Full path = /var/mobile/Containers/Data/Application/<UUID>/Documents

Result: works as expected, no errors thrown!

#2 new File(File.applicationDirectory.nativePath + "/\.\./Documents")  (iOS 8)

Full path = /private/var/mobile/Containers/Bundle/Application/<UUID>/Documents

Result: error, no write permission! (as I would expect with 'private' being there)


#3 File.documentsDirectory (iOS 7)

Full path = /var/mobile/Applications/<UUID>/Documents

Result: works as expected!


#4 new File(File.applicationDirectory.nativePath + "/\.\./Documents")  (iOS 7)

Full path = /var/mobile/Applications/<UUID>/Documents

Result: works as expected! (notice it's exactly the same as #3)


So, while the storage directory is easily adjustable and #1 should fit the bill nicely, I'm thinking of how to preserve user data when people begin updating from iOS 7 to iOS 8 as it will be kind of hard for me to locate my earlier data on iOS8 unless part of the update process is to also relocate all application data? I mean, even if I had used File.documentsDirectory before, this would still be a potential problem? In any case, it's obvious the iOS8 file system is different.


How is this going to work?

jadams602
Inspiring
July 22, 2014

Well I think this clearly shows that #1 is the way to go, yes it looks like Apple is moving the location of the apps in iOS 8 on the filesystem, but obviously the update on a device to the new OS version would have to move all apps, otherwise every single app would break.

It is clear that the reason you should always use helper aliases like File.documentsDirectory is that Adobe is properly relying on the native OS to resolve the documents folder no matter what OS version you are running on.