File read problems on Xamarin + iOS

The repro code for this post can be found here: https://github.com/jakkaj/Repro.

Note: The solution to the problem is not in that repro, it’s below. The repro helped us figure out what was happening.

I was having some quite severe issues when reading content in my Xamarin.iOS app. Data would either come back corrupted (out of order) or the file read operation would return the entirely wrong data (old data!).

The corruptions were what tipped it off first. We were saving serialised entities to the filesystem but when reading them back again the JSON parser started throwing errors. The text would be out of order, parts replicated, and double end braces and other strange bits and bobs.

The problem was using IsolatedStorageFile! Don’t use it! It sort of works sometimes… seems the problems occur after a while. I didn’t get to the bottom of exactly what was causing the problem or why, but essentially don’t use it!

Instead use File.WriteAllText and the other related methods as outlined in the Xamarin documentation here: http://developer.xamarin.com/guides/ios/application_fundamentals/working_with_the_file_system/.

For a working example see https://github.com/jakkaj/Xamling-Core/blob/master/XamlingCore/XamlingCore.iOS/Implementations/LocalStorage.cs.

 


        public async Task<bool> SaveString(string fileName, string data)
        {           
           var path = _getPath(fileName);
            _createDirForFile(path);

            File.WriteAllText(path, data);
            return true;
        }

        void _createDirForFile(string fileName)
        {
            var dir = Path.GetDirectoryName(fileName);

            //Debug.WriteLine("Creating Directory: {0}", fileName);

            if (dir == null)
            {
                return;
            }

            if (!Directory.Exists(dir))
            {
                Directory.CreateDirectory(dir);
            }
        }

        // <summary>
        /// iOS 8 Specific get path
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        private string _getPath(string fileName)
        {
            var documents = NSFileManager.DefaultManager.GetUrls(NSSearchPathDirectory.LibraryDirectory, NSSearchPathDomain.User)[0];
            var str = documents.Path;
            var result = Path.Combine(str, fileName);
            return result;
        }

Jordan.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s