How to open PDF file in iOS?

NyxeroNyxero USMember

I try to open a existing PDF file on a iOS device. This file have to be open with the default PDF reader.

In this moment i use the "dependency service" to run native code.

public void Save(string filename, byte[] byPDF)
{
    string strPfad = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), filename);
    if(File.Exists(strPfad))
    {
        File.Delete(strPfad);
        File.WriteAllBytes(strPfad, byPDF);
    }
    else
        File.WriteAllBytes(strPfad, byPDF);

    var viewer = UIDocumentInteractionController.FromUrl(NSUrl.FromFilename(strPfad));
    var controller = GetVisibleViewController();
    viewer.PresentOpenInMenu(controller.View.Frame, controller.View, true);
}

private UIViewController GetVisibleViewController(UIViewController controller = null)
{
    controller = controller ?? UIApplication.SharedApplication.KeyWindow.RootViewController;

    if (controller.PresentedViewController == null)
        return controller;

    if (controller.PresentedViewController is UINavigationController)
    {
        return ((UINavigationController)controller.PresentedViewController).VisibleViewController;
    }

    if (controller.PresentedViewController is UITabBarController)
    {
        return ((UITabBarController)controller.PresentedViewController).SelectedViewController;
    }

    return GetVisibleViewController(controller.PresentedViewController);
}

If I run this code is nothing happend (only the file becomes written).

Tagged:

Answers

  • JakovljevicIgorJakovljevicIgor ✭✭✭ USMember ✭✭✭

    @Nyxero one workaround would be to open the PDF in a web view.

  • NyxeroNyxero USMember

    @JakovljevicIgor
    I know, but I want to open it with the default PDF reader.

  • JakovljevicIgorJakovljevicIgor ✭✭✭ USMember ✭✭✭
    edited March 2017

    @Nyxero Hmmm try this

    partial void OpenFile (NSObject sender)
    {
    string path = Environment.GetFolderPath (Environment.SpecialFolder.Personal);
    string filePath = Path.Combine(path, "sample.pdf");
    var viewer = UIDocumentInteractionController.FromUrl(NSUrl.FromFilename(filePath));
    viewer.PresentOpenInMenu(new RectangleF(0,-260,320,320),this.View, true);
    }

    This worked for me :) But I see it is similar to yours. Maybe create a sample app and try it there

  • NyxeroNyxero USMember

    There is a problem with: "this.View".

    viewer.PresentOpenInMenu(new RectangleF(0,-260,320,320),**this.View**, true);
    

    Does not contain.

  • JakovljevicIgorJakovljevicIgor ✭✭✭ USMember ✭✭✭

    @Nyxero Are you trying to do this in the ViewController or the DataSource? If you are doing it in the ViewController, this should contain the view, if you added it through the Storyboard. If you are doing it in the DataSource, try to pass the View as a weak reference to the DataSource. (<-- This is bad). If you share more information, I can help you more :D :D

  • NyxeroNyxero USMember

    @JakovljevicIgor Okay.

    The project is a Xamarin.Forms application.
    This application have to run on Android and iOS.
    Moste of the code is running in the Protable project.

    Only one thing is running native.

    • Saving and opening a PDF file.

    On Android everythin works fine.

    All the following, is running after clicking on a Xamarin.Forms Button.

    First of all it´s run a "DependencyService"

    OpenPdf = new Command(async () => { byte[] pdf = await GetInvoicePdf(); DependencyService.Get<_IPDF>().Save("Rechnung.pdf", pdf); });

    • _IPDF is a simple interface class (as own project) with following source code

    namespace IPDF { public interface _IPDF { void Save(string filename, byte[] byPDF); } }

    • Class inside the iOS Project.
      `[assembly: Xamarin.Forms.Dependency(typeof(PDF))]
      namespace Eingangsrechnung.iOS
      {
      class PDF : _IPDF
      {
      public PDF()
      {

      }
      public void Save(string filename, byte[] byPDF)
      {
          string strPfad = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), filename);
          if(File.Exists(strPfad))
          {
              File.Delete(strPfad);
              File.WriteAllBytes(strPfad, byPDF);
          }
          else
              File.WriteAllBytes(strPfad, byPDF);
      
          var viewer = UIDocumentInteractionController.FromUrl(NSUrl.FromFilename(strPfad));
          var controller = GetVisibleViewController();
          viewer.PresentOpenInMenu(controller.View.Frame, controller.View, true);
      }
      
      private UIViewController GetVisibleViewController(UIViewController controller = null)
      {
          controller = controller ?? UIApplication.SharedApplication.KeyWindow.RootViewController;
      
          if (controller.PresentedViewController == null)
              return controller;
      
          if (controller.PresentedViewController is UINavigationController)
          {
              return ((UINavigationController)controller.PresentedViewController).VisibleViewController;
          }
      
          if (controller.PresentedViewController is UITabBarController)
          {
              return ((UITabBarController)controller.PresentedViewController).SelectedViewController;
          }
      
          return GetVisibleViewController(controller.PresentedViewController);
      }
      

      }
      }`

    Thas UI have to show on a Xamarin.Form file (InvoiceDetails.xaml).
    For this Page exist a ViewModel.

  • NyxeroNyxero USMember

    @JakovljevicIgor Okay.

    The project ist a Xamarin.Forms application.
    This application have to run on Android and iOS.
    Moste of the code is running in the Protable project.

    Only one thing is running native.

    • Saving and opening a PDF file.

    On Android everythin works fine.
    Now I try to creat the same native function for iOS.

    All the following is running after clicking on a Xamarin.Forms Button.

    First of all it´s run a "DependencyService"

    OpenPdf = new Command(async () => { byte[] pdf = await GetInvoicePdf(); DependencyService.Get<_IPDF>().Save("Rechnung.pdf", pdf); });

    _IPDF is a simple interface class with following source code.

    namespace IPDF { public interface _IPDF { void Save(string filename, byte[] byPDF); } }

    • Class inside the iOS Project.
      `[assembly: Xamarin.Forms.Dependency(typeof(PDF))]
      namespace Eingangsrechnung.iOS
      {
      class PDF : _IPDF
      {
      public PDF()
      {

          }
      
          public void Save(string filename, byte[] byPDF)
          {
              string strPfad = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), filename);
              if(File.Exists(strPfad))
              {
                  File.Delete(strPfad);
                  File.WriteAllBytes(strPfad, byPDF);
              }
              else
                  File.WriteAllBytes(strPfad, byPDF);
      
              var viewer = UIDocumentInteractionController.FromUrl(NSUrl.FromFilename(strPfad));
              var controller = GetVisibleViewController();
              viewer.PresentOpenInMenu(controller.View.Frame, controller.View, true);
          }
      
          private UIViewController GetVisibleViewController(UIViewController controller = null)
          {
              controller = controller ?? UIApplication.SharedApplication.KeyWindow.RootViewController;
      
              if (controller.PresentedViewController == null)
                  return controller;
      
              if (controller.PresentedViewController is UINavigationController)
              {
                  return ((UINavigationController)controller.PresentedViewController).VisibleViewController;
              }
      
              if (controller.PresentedViewController is UITabBarController)
              {
                  return ((UITabBarController)controller.PresentedViewController).SelectedViewController;
              }
      
              return GetVisibleViewController(controller.PresentedViewController);
          }
      }
      

      }`

    All this code is running native on iOS.
    Now I need the created UI for die Xamarin.Forms Page (InvoiceDetails.xaml with a ViewModel).

  • dsfqfdsfdsfqdsdsfqfdsfdsfqds ✭✭ USMember ✭✭

    still nothing?...

  • SchmickeySchmickey Member

    6 months later and I've been struggling with the exact same problem.
    The solution which worked for me was to use topic 103042 (sorry I can't post link as I'm too new, but if you navigate to ~/discussion/103042 you'll find the post I'm referring to) in combination with your GetVisibleViewController() method.
    i.e Replace UIApplication.SharedApplication.KeyWindow.RootViewController with GetVisibleViewController()

    This pushes the default document previewer onto the Navigation stack modaly, it doesn't give you the option to open it with an external app. Hope this helps.

  • AlexMAlexM ✭✭ Member ✭✭

    Thanks @Schmickey. Indeed I found a working solution there. Follow PassionateCreative implementation!
    The get there go... (forums.xamarin.com/discussion/103042).

Sign In or Register to comment.