{"id":37511,"date":"2018-07-25T14:21:06","date_gmt":"2018-07-25T21:21:06","guid":{"rendered":"https:\/\/blog.xamarin.com\/?p=37511"},"modified":"2019-09-23T08:15:11","modified_gmt":"2019-09-23T15:15:11","slug":"previewing-files-with-xamarin-ios","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/xamarin\/previewing-files-with-xamarin-ios\/","title":{"rendered":"Previewing Files Inside Your Xamarin.iOS App"},"content":{"rendered":"<p>\t\t\t\tIf your app interacts with files, such as email attachments or photos, allowing users to preview those files without leaving your app is a great way to enhance the user&#8217;s experience. Fortunately, iOS makes adding this feature simple by providing the document interaction controller and the Quick Look preview controller. In this post, you will learn the differences between the two options and how you can implement them in your app.<\/p>\n<p>All the code below is available as a <a href=\"https:\/\/github.com\/jimmgarrido\/document-interaction-sample\">sample app on GitHub<\/a>.<\/p>\n<h2>Document Interaction Controller<\/h2>\n<p>The <a href=\"https:\/\/developer.xamarin.com\/api\/type\/UIKit.UIDocumentInteractionController\/\">document interaction controller<\/a> is the more straightforward option to implement. As the name suggests, not only can it be used for previewing, it can also enable other file interactions, such as opening with another app, copying, or printing.<\/p>\n<p>To use the document interaction controller, start by creating a class that inherits from <a href=\"https:\/\/developer.xamarin.com\/api\/type\/UIKit.UIDocumentInteractionControllerDelegate\/\"><code>UIDocumentInteractionControllerDelegate<\/code><\/a>. While most of the delegate methods are optional, in order to enable previewing you must override the <code>ViewControllerForPreview<\/code> method. This method must return a view controller that the document interaction controller can use as its parent. You can define a constructor with a <code>UIViewController<\/code> parameter so you can pass in the parent view controller:<\/p>\n<pre class=\"theme:vs2012 lang:cs decode:true\">public class MyInteractionDelegate : UIDocumentInteractionControllerDelegate\r\n{\r\n    UIViewController parent;\r\n\r\n    public MyInteractionDelegate(UIViewController controller)\r\n    {\r\n        parent = controller;\r\n    }\r\n\r\n    public override UIViewController ViewControllerForPreview(UIDocumentInteractionController controller)\r\n    {\r\n        return parent;\r\n    }\r\n}\r\n<\/pre>\n<p>When you are ready to present the preview, create a new document interaction controller by using the <code>UIDocumentInteractionController.FromUrl<\/code> method and passing it the path to the file. Then set its <code>Delegate<\/code> property to a new instance of the class above and call <code>PresentPreview<\/code>:<\/p>\n<pre class=\"theme:vs2012 lang:cs decode:true\">var previewController = UIDocumentInteractionController.FromUrl(\r\n    NSUrl.FromFilename(\"sampledocs\/gettingstarted.pdf\"));\r\n\r\npreviewController.Delegate = new MyInteractionDelegate(this);\r\npreviewController.PresentPreview(true);\r\n<\/pre>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/document-interaction.gif\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-37540\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/document-interaction.gif\" alt=\"Gif demonstrating the document interaction controller opening a preview of a pdf document followed by a photo\" width=\"280\" height=\"500\" \/><\/a><\/p>\n<h3>Other Interaction Options<\/h3>\n<p>As mentioned earlier, the document interaction controller offers more than just previews. Calling <code>PresentOptionsMenu<\/code> instead will present a menu with apps installed that can open the file and other options such as copying or printing the file. <code>PresentOpenInMenu<\/code> is similar except it will only show the list of apps that can open the file.<\/p>\n<p><figure id=\"attachment_37550\" aria-labelledby=\"figcaption_attachment_37550\" class=\"wp-caption aligncenter\" ><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/interaction-options.png\"><img decoding=\"async\" class=\"wp-image-37550\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/interaction-options.png\" alt=\"Screenshot of menu options for PresentOptionsMenu and PresentOpenInMenu\" width=\"650\" height=\"500\" \/><\/a><figcaption id=\"figcaption_attachment_37550\" class=\"wp-caption-text\">Menu options for PresentOptionsMenu (left) and PresentOpenInMenu (right)<\/figcaption><\/figure><\/p>\n<h2>Quick Look Preview Controller<\/h2>\n<p>Unlike the document interaction controller, the <a href=\"https:\/\/developer.xamarin.com\/api\/type\/QuickLook.QLPreviewController\/\">Quick Look preview controller<\/a> can only preview files. It also requires a data source, however, the benefit of this is that it can preview multiple files at the same time.<\/p>\n<p>To begin, create a class that inherits from <a href=\"https:\/\/developer.xamarin.com\/api\/type\/QuickLook.QLPreviewControllerDataSource\/\"><code>QLPreviewControllerDataSource<\/code><\/a>. You will need to override the following methods:<\/p>\n<ul>\n<li><code>PreviewItemCount<\/code> &#8211; returns an <code>nint<\/code> for the number of files to be previewed.<\/li>\n<li><code>GetPreviewItem<\/code> &#8211; returns the current preview item. The object must implement <a href=\"https:\/\/developer.xamarin.com\/api\/type\/QuickLook.IQLPreviewItem\/\"><code>IQLPreviewItem<\/code><\/a> in order to provide the controller the path to the file.<\/li>\n<\/ul>\n<p>Create a new class inheriting from <a href=\"https:\/\/developer.xamarin.com\/api\/type\/QuickLook.QLPreviewItem\/\"><code>QLPreviewItem<\/code><\/a> and override the <code>ItemUrl<\/code> method to return the file&#8217;s path. You can also override <code>ItemTitle<\/code> if you want to customize the title that is shown for the preview.<\/p>\n<pre class=\"theme:vs2012 lang:cs decode:true\">public class QuickLookSource : QLPreviewControllerDataSource\r\n{\r\n    List documents;\r\n\r\n    public QuickLookSource(List docs)\r\n    {\r\n        documents = docs;\r\n    }\r\n\r\n    public override nint PreviewItemCount(QLPreviewController controller)\r\n    {\r\n        return documents.Count;\r\n    }\r\n\r\n    public override IQLPreviewItem GetPreviewItem(QLPreviewController controller, nint index)\r\n    {\r\n        return new PreviewItem(documents[(int)index]);\r\n    }\r\n}\r\n\r\npublic class PreviewItem : QLPreviewItem\r\n{\r\n    NSUrl fileUrl;\r\n\r\n    public override NSUrl ItemUrl =&gt; fileUrl;\r\n    public override string ItemTitle =&gt; fileUrl.LastPathComponent;\r\n\r\n    public PreviewItem(string url)\r\n    {\r\n        fileUrl = NSUrl.FromFilename(url);\r\n    }\r\n}\r\n<\/pre>\n<p>To present a preview, create a new <code>QLPreviewController<\/code> and set <code>DataSource<\/code> to you data source class. Since the controller can preview multiple files, make sure to set <code>CurrentPreviewItemIndex<\/code> before navigating to the controller:<\/p>\n<pre class=\"theme:vs2012 lang:cs decode:true\">var previewController = new QLPreviewController();\r\npreviewController.DataSource = new QuickLookSource(source.Documents);\r\n\r\npreviewController.CurrentPreviewItemIndex = indexPath.Row;\r\nNavigationController.PushViewController(previewController, true);\r\n\r\n\/\/ You can present modally instead\r\n\/\/ PresentViewController(previewController, true, null);  \r\n<\/pre>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/quick-look-ios.gif\"><img decoding=\"async\" class=\"aligncenter size-full wp-image-37544\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/44\/2019\/03\/quick-look-ios.gif\" alt=\"Gif showing the Quick Look controller opening a preview of multiple files\" width=\"280\" height=\"500\" \/><\/a><\/p>\n<h2>Wrap up<\/h2>\n<p>Adding file previews to your app can be a quick and simple way to increase user engagement in your app. This post gave you an overview on how to get started with file previews so check out <a href=\"https:\/\/developer.apple.com\/library\/archive\/documentation\/FileManagement\/Conceptual\/DocumentInteraction_TopicsForIOS\/Introduction\/Introduction.html#\/\/apple_ref\/doc\/uid\/TP40010409-SW1\">Apple&#8217;s documentation<\/a> to learn even more about interacting with documents on iOS. Happy coding!\t\t<\/p>\n","protected":false},"excerpt":{"rendered":"<p>If your app interacts with files, such as email attachments or photos, allowing users to preview those files without leaving your app is a great way to enhance the user&#8217;s experience. Fortunately, iOS makes adding this feature simple by providing the document interaction controller and the Quick Look preview controller. In this post, you will learn the differences between the two options and how you can implement them in your app.<\/p>\n","protected":false},"author":1441,"featured_media":40985,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[303,291],"tags":[1037,6],"class_list":["post-37511","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ios","category-xamarin-platform","tag-files","tag-ios"],"acf":[],"blog_post_summary":"<p>If your app interacts with files, such as email attachments or photos, allowing users to preview those files without leaving your app is a great way to enhance the user&#8217;s experience. Fortunately, iOS makes adding this feature simple by providing the document interaction controller and the Quick Look preview controller. In this post, you will learn the differences between the two options and how you can implement them in your app.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/37511","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/users\/1441"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/comments?post=37511"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/posts\/37511\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media\/40985"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/media?parent=37511"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/categories?post=37511"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/xamarin\/wp-json\/wp\/v2\/tags?post=37511"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}