Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you load a file from an absolute NSURL in xamarin

I'm developing an App using Xamarin for IOS, used the opengl game template as a start.

I have set up my app to be able to open a certain file format, and have overriden the OpenURL delegate in the AppDelegate.cs

the problem is if I do this:

 public override bool OpenUrl(UIApplication application, NSUrl url, string sourceApplication, NSObject annotation)
        {

            Stream bob = new FileStream(url.AbsoluteString, FileMode.Open,  FileAccess.Read);
            return true;
        }

I get an exception something along the lines of

"Unable to open file : /private/var/mobile/Applications/A7B5E435-F7D1-4985-BA97-C243E63EFC39/MyApp.app/file:///private/var/mobile/Applications/A7B5E435-F7D1-4985-BA97-C243E63EFC39/Documents/Inbox/A%20File%20To%20Open.ext"

This seems to be because url.AbsoluteString returns the file:///... part but FileStream always wants a more sanitized path (with the %20s replaced with spaces for example) relative to what must be the app's bundle dir

/private/var/mobile/Applications/A7B5E435-F7D1-4985-BA97-C243E63EFC39/MyApp.app/

In the end I got it to work in the very hack way of taking the url.AbsoluteString, removing the "file:///" part, adding a bunch of ../../../ etc to the begining, and replacing "%20" with " ".

 public override bool OpenUrl(UIApplication application, NSUrl url, string sourceApplication, NSObject annotation)
        {
            string fname = "../../../../../../../../../" + (url.AbsoluteString).Replace("%20", " ").Replace("file:///","");
            Stream bob = new FileStream(fname, FileMode.Open,  FileAccess.Read);
            return true;
        }

And this worked... but it seems horribly hack. So what is the correct way to get a readable file stream from an NSURL that points to a file, using Xamarin?

(note this was on IOS 7, in IOS 9, the path passed in is different to FileStream's default dir in many ways and at a high level in the dir tree too)

like image 427
matt Avatar asked Apr 13 '16 00:04

matt


2 Answers

Use the Path property on the NSUrl class:

NSString urlString = new NSString("file:///stack/over%20flow/foobar.txt");
NSUrl myFileUrl = new NSUrl (urlString);
Console.WriteLine (myFileUrl.AbsoluteString);
string absPath = myFileUrl.Path;
Console.WriteLine (absPath);

2016-04-12 18:38:53.809 filepath[11174:1132929] file:///stack/over%20flow/foobar.txt
2016-04-12 18:38:53.814 filepath[11174:1132929] /stack/over flow/foobar.txt

Ref: https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSURL_Class/index.html#//apple_ref/occ/instp/NSURL/path

like image 190
SushiHangover Avatar answered Sep 27 '22 22:09

SushiHangover


You can retrieve the file path component of the NSUrl through the Path property:

string fname = url.Path;
Stream bob = new FileStream(fname, FileMode.Open,  FileAccess.Read);
return true;

This will return the absolute filepath and decode %20 into spaces.

like image 36
matthewrdev Avatar answered Sep 27 '22 21:09

matthewrdev