Hello and welcome

to Intellicore’s blog where we will give you info on relevant topics in relation to IT. We see the blog as a joint effort and would love to hear what you would like us to feature (there’s no point in us writing a blog that’s not of interest and we’d hate to bore you…)

MonoTouch iOS Applications - Documents Directory & FileStream

We’re all about solutions at Intellicore – we’ve written the following article to address a very specific problem that took one of the team quite some time to figure out in regards to accessing the main bundle on an iPh-one/iPad device via MonoTouch (C# code).

The problem was that, as a developer to use the problem code mentioned in the article would have prevented the user from accessing certain files in the main bundle and using them within the application itself.   We’ve gone through extensive trial and error so you don’t have to - in order to find the solution to what is really quite a simple problem.

Recently, while developing an iPhone application in MonoTouch a bug presented itself meaning that access to certain files within the main bundle on the iPhone device was not available.  The directory existed in the main bundle because the following code returned 'got it':

if (Directory.Exists (NSBundle.MainBundle.BundlePath + "/TheDirectory")) {
    Console.WriteLine ("got it");
    } else {
      Console.WriteLine ("can't find it");
       }

Where "TheDirectory" is the directory our developer was trying to access within the main bundle.  Eventually we managed to figure out the problem, it was to do with the FileStream.  In the program, there were several occurrences of the line (or similar):

fs = new FileStream(fileName, FileMode.Open);

Now, if you’re a savvy iPhone developer, you'll know the main bundle is read-only.  This line caused a problem because unless you explicitly specify the type of FileAccess in the FileStream constructor, it will default to File-Access.ReadWrite.  This caused the following stack trace to be generated:

System.InvalidOperationException: Operation is not valid due to the current state of the object
  at System.Linq.Enumerable.Max[TileIndexRecord] (IEnumerable`1 source, System.Func`2 selector) [0x00000] in <filename unknown>:0
  at MyCompany.Data.Arcs.Loader.ExtractWriteableBitmap (MyCompany.Data.Arcs.Records.RGBPaletteRecord rgbPalette, Double dpi, MyCompany.Data.Arcs.Raschts.ChartIndexFile indexFile, MyCompany.Data.Arcs.Raschts.RasterChartFile chartFile) [0x00000] in /Users/me/Desktop/ARCSViewer/ARCSViewer/Loader.cs:571
  at MyCompany.Data.Arcs.Loader.GetHiResImage (MyCompany.Data.Arcs.Records.RGBPaletteRecord rgbPal-ette) [0x00000] in /Users/me/Desktop/ARCSViewer/ARCSViewer/Loader.cs:362
  at ARCSViewer.SecondViewController.generateChart (Int32 chartNumber, System.String palette) [0x0004e] in /Users/me/Desktop/ARCSViewer/ARCSViewer/SecondViewController.cs:118
  at ARCSViewer.SecondViewController.ViewDidAppear (Boolean animated) [0x00007] in /Users/me/Desktop/ARCSViewer/ARCSViewer/SecondViewController.cs:84
  at MonoTouch.UIKit.UIApplication.Main (System.String[] args, System.String principalClassName, System.String delegateClassName) [0x0004c] in /Developer/MonoTouch/Source/monotouch/src/UIKit/UIApplication.cs:38
  at ARCSViewer.Application.Main (System.String[] args) [0x00000] in /Users/me/Desktop/ARCSViewer/ARCSViewer/Main.cs:17

This was preventing us from accessing the files in the main bundle.  In-order to circumvent this problem, all occurrences of the FileStream constructor mentioned above were changed to:

fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);

This forced the FileStream into a read-only state and allowed access the files in the main bundle.


At Intellicore, we specialise in mobile application development (click to find out more) and would gladly take on projects that require solutions for multiple types of mobile platforms, from iPhone and iPads to Android-based devices.



2 comments :