Skip to content

IsolatedStorageFile.GetUserStoreForApplication path changes between Xamarin.iOS and .NET 6 builds on iOS #74642

Closed

Description

@dtaylorus

Description

The path of a file created by IsolatedStorageFile.GetUserStoreForApplication() changes between Xamarin.iOS and .NET 6, and also changes between different builds of the application under .NET 6.

This makes IsolatedStorageFile unusable in .NET 6 since an updated build cannot open a file created by a previous build. Each time the build is updated, all of the files previously created on behalf of the user are effectively gone.

For example, the following code:

    using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication()) {
        using (IsolatedStorageFileStream stream = store.OpenFile("settings.txt", FileMode.Create)) {
            // Write file contents here

results in the file being written to various locations in the iOS device file system depending on the build of the application:

/var/mobile/Containers/Data/Application/<GUID>/Documents/IsolatedStorage/tz12rggn.q0z/hi51wlzn.hmf/Url.j1gfq4nxq1m4zfi31rjvtcuna3umf3fb/AppFiles/settings.txt
/var/mobile/Containers/Data/Application/<GUID>/Documents/IsolatedStorage/tz12rggn.q0z/hi51wlzn.hmf/Url.vb0fraupqrlwtvom530yjpnqlhlbggfc/AppFiles/settings.txt
/var/mobile/Containers/Data/Application/<GUID>/Documents/IsolatedStorage/tz12rggn.q0z/hi51wlzn.hmf/Url.az1iqc1z0lv42e3agh4zvg5aa5rbihzj/AppFiles/settings.txt
/var/mobile/Containers/Data/Application/<GUID>/Documents/IsolatedStorage/tz12rggn.q0z/hi51wlzn.hmf/Url.efra4nhzgkrws2l30v4hbayjiohm2ofj/AppFiles/settings.txt
...

In Xamarin.iOS the path of the file was consistent across builds of the app.

Reproduction Steps

Build the code below on Xamarin.iOS and execute on an iOS device.
Migrate the app to dotnet 6, rebuild and execute on the same iOS device.
Note that the file is created in a different file system location on the device.
Clean and rebuild the dotnet 6 app and execute on the same iOS device.
Note that the file is created in yet another file system location on the device.

    using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication()) {
        using (IsolatedStorageFileStream stream = store.OpenFile("settings.txt", FileMode.Create)) {
        }
    }

Expected behavior

The settings.txt file should be created in the same file system location (path) for every version of the built application.

Actual behavior

The settings.txt file is created in a different file system location (path) for every version of the built application on dotnet 6

Regression?

Yes, this is a regression. The file system path for IsolatedStorageFile was consistent in .NET Framework applications I've built over the past decade with many different versions of .NET and Xamarin.iOS.

Known Workarounds

I don't know of any workaround using the .NET 6 IsolatedStorageFile API. Applications would have to use some other file system API and maybe Environment.GetFolderPath(SpecialFolder folder).

Configuration

.NET 6
iOS
ARM64

This issue is specific to .NET 6 on iOS

Other information

No response

Activity

  1. ghost added
    untriagedNew issue has not been triaged by the area owner
    on Aug 26, 2022
  2. dtaylorus commented on Aug 26, 2022

    @dtaylorus
    Author

    The legacy IsolatedStorageFile.GetUserStoreForApplication() folder on Xamarin.iOS is:

        /var/mobile/Containers/Data/Application/<GUID>/Documents/.config/.isolated-storage/
    

    As a workaround, this path can be recreated manually in .NET 6 using Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) as the base path and appending ".config/.isolated-storage/".

    Legacy files can then be accessed using System.IO.File instead of IsolatedStorageFile.

  3. changed the title [-]IsolatedStorageFile.GetUserStoreForApplication path changes between Xamarin.iOS and dotnet 6 builds on iOS[/-] [+]IsolatedStorageFile.GetUserStoreForApplication path changes between Xamarin.iOS and .NET 6 builds on iOS[/+] on Aug 27, 2022
  4. dtaylorus commented on Aug 27, 2022

    @dtaylorus
    Author

    This is broken in the same way on Android. The legacy IsolatedStorageFile.GetUserStoreForApplication() folder on Xamarin.Android is:

        /data/user/0/<PackageId>/files/.config/.isolated-storage/
    

    As a workaround, this legacy path can be recreated manually in .NET 6 using Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData) as the base path and appending ".config/.isolated-storage/".

    Legacy files can then be accessed using System.IO.File instead of IsolatedStorageFile.

  5. mkhamoyan commented on Aug 30, 2022

    @mkhamoyan
    Contributor

    Hi @dtaylorus,
    I was trying to reproduce it locally from both runtime and from maui app, but still I can see after several builds same URl."hash". Here are my steps from maui.

    1. Created Maui app and added these lines
      using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication()) {
      using (IsolatedStorageFileStream stream = store.OpenFile("settings.txt", FileMode.Create)) {
      // Write file contents here
    2. Tried several times clean/build, uninstalling app from phone but the root is still the same.
      This was what I saw for several builds
      "/data/user/0/com.companyname.testmaui/files/IsolatedStorage/0h0aylru.guc/lh5b4jf5.cnu/Url.kvaj4cxhwjeypoiko55puloz0kgusnnw/AppFiles/"

    I'm trying on Android device, running on Debug mode using Visual Studio 2022 for Mac v17.4 Preview. (For release mode unfortunately I still have exception while running, working on it)
    Could you please add more details which mode are you running and if possible upload your project ?

  6. dtaylorus commented on Aug 30, 2022

    @dtaylorus
    Author

    Probably the simplest thing to do is create the same project for legacy Xamarin.Android (not .NET 6) and see that the path is completely different and doesn't even contain the 'Url' part of the path that is new in .NET 6 for Android.

    This means that projects that were released on legacy Xamarin.Android will lose access to files created with IsolatedStorageFile after upgrading the project to .NET 6.

    If this backward compatibility issue is fixed, the part of this issue about the path constantly changing will be irrelevant anyway since there won't be a Url part of the path that can change.

    Also note that I found the behavior about the path changing on .NET 6 for iOS, not Android. I only verified that the backward compatibility issue exists on Android (where the path changes between Xamarin.Android and .NET 6 for Android). I have not tested for the changing path between builds on Android being the same as on iOS.

    Hope that makes sense. Thanks for looking into this issue

  7. dtaylorus commented on Aug 30, 2022

    @dtaylorus
    Author

    To answer your specific questions, I'm building on Visual Studio 2022 for Windows. My Android builds are local (SDK version 33) and my iOS builds are via a remote connection to a MacOS machine. I've tested in both debug and release builds and the results appear to be the same.

    My project is a released app that is way too big to share. I encountered this problem when I was forced to upgrade the project to .NET 6 because of some dependencies. I was able to work around the issue by replacing all references to IsolatedStorageFile with direct use of System.IO.File.

  8. removed
    untriagedNew issue has not been triaged by the area owner
    on Sep 12, 2022
  9. added this to the 8.0.0 milestone on Sep 12, 2022
  10. 13 remaining items

  11. added 11 commits that reference this issue on Sep 27, 2022
  12. akoeplinger commented on Sep 28, 2022

    @akoeplinger
    Member

    This was fixed in main with #74642 and we have a backport PR open to fix it for .NET 7 with #76254

  13. dtaylorus commented on Sep 28, 2022

    @dtaylorus
    Author

    Fantastic. Thanks all!

  14. ghost locked as resolved and limited conversation to collaborators on Oct 29, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions