0

I am trying to open a *.epub file throught my application and I don't quite understand how to make it with the UIDocumentInteractionController class. I have seen the official IOS documentation and examples and some of the examples over the net but I don't understand how that class works. This is how I do it, what I achieve and what I dont understand:

I have a UIView with a UIButton:

using MonoTouch.UIKit;
using MonoTouch.Foundation;
using System.Drawing;

public class MyView : UIViewController
{
    UIButton myBtn;

    public MyView() :base()
    {
        View.Frame = new RectangleF(0,0,1024,768);

        var myRect = new RectangleF(300,300,100,50);

        myBtn = UIButton.FromType(UIButtonType.RoundedRect);
        myBtn.Frame = myRect;
        myBtn.TouchUpInside += delegate
        {
            var dic = UIDocumentInteractionController.FromUrl(new NSUrl("http://192.168.50.50:2020/myfile.epub"));
            var dicDel = new UIDocumentInteractionControllerDelegate();
            dic.Delegate = dicDel;

            InvokeOnMainThread(delegate
            {
                var result = dic.PresentOpenInMenu(myRect, View, true);
                //If I do this -> NullReferenceException because delegate is null (something about autorelease?? Don't know)
                if(!result) dic.Delegate.DidDismissOpenInMenu(dic);
            });


        }
    }
}

The weirdest thing is if I debug and inspect "dic" (without the delegate) before calling the PresentOpenInMenu() method it shows the menu (returning true) but just after doing it the app blows up on Main.cs because the autorelease thing I dont understand.

I am a little lost. Can someone help me understand this class and how can I make it work correctly? Thanks in advance.

EDIT: By the way, I used a *.txt file too with same results.

Community
  • 1
  • 1
David Diez
  • 1,165
  • 1
  • 11
  • 23
  • I just tried your example and the error I get is: UIDocumentInteractionController: invalid scheme http. Only the file scheme is supported. – slott Aug 31 '12 at 11:14

1 Answers1

0

It looks like a MonoTouch bug. Setting the UIDocumentInteractionController.Delegate (or WeakDelegate property and then querying its value returns null (which will fail later on).

I'll look into this bug and update this answer if I can provide a workaround (until the bug is properly fixed in a future release of MonoTouch).

UPDATE: UIDocumentInteractionController already creates it's own internal UIDocumentInteractionControllerDelegate so you do not need to create one. The Delegate methods, like DidDismissOpenInMenu are available as events on UIDocumentInteractionController itself.

Remove your own Delegate (creation and set) and use the events and you should be fine.

UPDATE #2: The Delegate property returns null since the default UIDocumentInteractionControllerDelegate is not usable as is. It is meant to be inherited from and customized to do what you want to (and the unusable default one is not registred properly to be used). E.g.

class MyDocumentInteractionControllerDelegate : UIDocumentInteractionControllerDelegate { }

and

var dicDel = new MyDocumentInteractionControllerDelegate ();

would work, as in no NullReferenceException, but of course DidDismissOpenInMenu won't be doing anything interesting.

poupou
  • 43,413
  • 6
  • 77
  • 174
  • Thanks for your answer poupou, I already solved the issue. Indeed the delegate is not instanced and if you want to handle its events on your own you need to create a class inheriting the UIDocumentInteractionControllerDelegate class and overriding those methods, but if you only want to show the options/preview/openIn menu you don't need the delegate at all. – David Diez Nov 23 '11 at 18:01
  • Ok I was looking for my code but I don't have here now, so I will post it tomorrow, promise. The key thing was I was missing how to retain the object after calling it, I needed to make the declaration of the DocumentInteractionController as a property and put it the [Export ("PresentOptionsMenu", MonoTouch.ObjCRuntime.ArgumentSemantic.Retain)] attribute – David Diez Nov 23 '11 at 18:42
  • 1
    Providing a xxxDelegate is **optional** and allows you to customize the main class (`UIDocumentInteractionController` in this case). This is always supported in MonoTouch - but the base xxxDelegate class wont help since it's not doing anything (until you inherit from it). Some types, including `UIDocumentInteractionController` also **optionally** *hides* the xxxDelegate (it uses an internal one) and let you customize using C# events (which are more .NET friendly). – poupou Nov 23 '11 at 18:49