QLPreviewController fails in the iOS 15.5 devices on the Xamarin.Forms

Pelin Konaray 291 Reputation points
2023-01-06T13:23:59.503+00:00

Hello,

I have an Xamarin.Forms application that users can download the files from the remote server to the device. Later, when the user opens application to preview these files, QLPreviewController run with Dependency services to preview operation.

DependencyService.Get<IDocumentView>().DocumentView(filePath, filename);  

The DocumentView method in the IDocumentView dependency class also calls the PdfPreviewController in the iOS part. My code like this:

public interface IDocumentView  
{  
     void DocumentView(string file, string title);  
}  

using App.Helpers;  
 using App.iOS.CustomRenderer;  
 using App.Models;  
 using App.Views;  
 using Foundation;  
 using QuickLook;  
 using System;  
 using System.IO;  
 using System.Linq;  
 using UIKit;  
 using Xamarin.Forms;  
      
 [assembly: Dependency(typeof(DocumentView))]  
 namespace App.iOS.CustomRenderer  
 {  
     public class DocumentView : IDocumentView  
     {  
         void IDocumentView.DocumentView(string file, string title)  
         {  
             try  
             {  
                 if (VideoAudioControl(file))  
                 {  
                     OpenVideoAudioPreview(file, title);  
                 }  
                 else  
                 {  
                     UIApplication.SharedApplication.InvokeOnMainThread(() =>  
                     {  
                         PdfPreviewController previewController = new PdfPreviewController();  
      
                         if (File.Exists(file))  
                         {  
                             previewController.DataSource = new PDFPreviewControllerDataSource(NSUrl.FromFilename(file), title);  
                             UIApplication.SharedApplication.KeyWindow.RootViewController.PresentViewController(previewController, true, null);  
                         }  
                         MessagingCenter.Send("ClosePreviewPopup", "ClosePreviewPopup");  
                     });  
                 }  
             }  
             catch (Exception ex)  
             {  
                 Helper.Log(ex, "IDocumentView.DocumentView", "DocumentView", "IDocumentView.DocumentView(string file, string title)");  
             }  
         }  
     }  
      
     public class PDFItem : QLPreviewItem  
     {  
         public PDFItem(string title, NSUrl uri)  
         {  
             this.Title = title;  
             this.Url = uri;  
         }  
         public string Title { get; set; }  
         public NSUrl Url { get; set; }  
         public override NSUrl ItemUrl { get { return Url; } }  
         public override string ItemTitle { get { return Title; } }  
     }  
      
     public class PDFPreviewControllerDataSource : QLPreviewControllerDataSource  
     {  
         PDFItem[] sources;  
      
         public PDFPreviewControllerDataSource(NSUrl url, string filename)  
         {  
             sources = new PDFItem[1];  
             sources[0] = new PDFItem(filename, url);  
         }  
      
         public override IQLPreviewItem GetPreviewItem(QLPreviewController controller, nint index)  
         {  
             int idx = int.Parse(index.ToString());  
             if (idx < sources.Length)  
                 return sources.ElementAt(idx);  
             return null;  
         }  
      
         public override nint PreviewItemCount(QLPreviewController controller)  
         {  
             return (nint)sources.Length;  
         }  
     }  
 }  

public class PdfPreviewController : QLPreviewController  
    {  
        public PdfPreviewController()  
        {  
        }  
  
        public override void ReloadData()  
        {  
            try  
            {  
                base.ReloadData();  
            }  
            catch (Exception ex)  
            {  
                string exp = ex.Message;  
            }  
        }  
    }  

But when I open a file with PdfPreviewController/QLPreviewController on the iOS 15.5 devices, there is some error like this:
276810-image.png

Error detail:

Objective-C exception thrown.  Name: NSInvalidArgumentException Reason: *** -[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[2]\nNative stack trace:\n\t0   CoreFoundation                      0x000000010b3cc604 __exceptionPreprocess + 242\n\t1   libobjc.A.dylib                     0x0000000110ac3a45 objc_exception_throw + 48\n\t2   CoreFoundation                      0x000000010b44dc63 _CFThrowFormattedException + 200\n\t3   CoreFoundation                      0x000000010b458137 -[__NSPlaceholderDictionary initWithObjects:forKeys:count:].cold.5 + 0\n\t4   CoreFoundation                      0x000000010b43a928 -[__NSPlaceholderDictionary initWithObjects:forKeys:count:] + 243\n\t5   CoreFoundation                      0x000000010b3cb258 +[NSDictionary dictionaryWithObjects:forKeys:count:] + 49\n\t6   QuickLook                           0x000000010ba9d5de __49+[QLItem(PreviewInfo) contentTypesToPreviewTypes]_block_invoke + 484\n\t7   libdispatch.dylib                   0x00000001155edb25 _dispatch_client_callout + 8\n\t8   libdispatch.dylib                   0x00000001155eecdd _dispatch_once_callout + 20\n\t9   QuickLook                           0x000000010ba9d3f8 +[QLItem(PreviewInfo) contentTypesToPreviewTypes] + 46\n\t10  QuickLook                           0x000000010ba9dd39 -[QLItem(PreviewInfo) _uncachedPreviewItemTypeForContentType:] + 117\n\t11  QuickLook                           0x000000010ba9e2a6 -[QLItem(PreviewInfo) _previewItemTypeForType:] + 150\n\t12  QuickLook                           0x000000010ba9e0ac -[QLItem(PreviewInfo) _getPreviewItemType] + 61\n\t13  QuickLook                           0x000000010bb254da -[QLItem previewItemType] + 59\n\t14  QuickLook                           0x000000010bad4d1d +[QLItemFetcherFactory fetcherForPreviewItem:] + 90\n\t15  QuickLook                           0x000000010bb24ba3 -[QLItem fetcher] + 44\n\t16  QuickLook                           0x000000010ba88828 -[QLPreviewController previewItemAtIndex:withCompletionHandler:] + 153\n\t17  QuickLook                           0x000000010babe7af __63-[QLPreviewItemStore previewItemAtIndex:withCompletionHandler:]_block_invoke + 262\n\t18  QuickLook                           0x000000010baf2629 QLRunInMainThread + 51\n\t19  QuickLook                           0x000000010babe67a -[QLPreviewItemStore previewItemAtIndex:withCompletionHandler:] + 181\n\t20  QuickLook                           0x000000010ba82847 -[QLPreviewController internalCurrentPreviewItem] + 222\n\t21  QuickLook                           0x000000010bb02148 -[QLPreviewController(Overlay) _actionButton] + 344\n\t22  QuickLook                           0x000000010bb02824 -[QLPreviewController(Overlay) _toolBarButtonsWithTraitCollection:] + 1147\n\t23  QuickLook                           0x000000010bb00307 -[QLPreviewController(Overlay) _updateOverlayButtonsIfNeededWithTraitCollection:animated:updatedToolbarButtons:] + 129\n\t24  QuickLook                           0x000000010baff9aa -[QLPreviewController(Overlay) updateOverlayAnimated:animatedButtons:forceRefresh:withTraitCollection:] + 152\n\t25  QuickLook                           0x000000015038f955 -[QLPreviewControllerAccessibility updateOverlayAnimated:animatedButtons:forceRefresh:withTraitCollection:] + 84\n\t26  QuickLook                           0x000000010ba826af -[QLPreviewController _setCurrentPreviewItemIndex:updatePreview:animated:] + 230\n\t27  QuickLook                           0x000000010ba883be -[QLPreviewController reloadData] + 418\n\t28  App.iOS                       0x000000010297ee8c xamarin_dyn_objc_msgSendSuper + 220\n\t29  ???                                 0x000000014e1ea6a2 0x0 + 5605598882\n\t30  ???                                 0x0000000148b73746 0x0 + 5514934086\n\t31  Mono                                0x000000010bd070b5 mono_jit_runtime_invoke + 1621\n\t32  Mono                                0x000000010befc1e8 mono_runtime_invoke_checked + 136\n\t33  Mono                                0x000000010beffb0e mono_runtime_invoke + 142\n\t34  App.iOS                       0x000000010297621b xamarin_invoke_trampoline + 6219\n\t35  App.iOS                       0x000000010297da09 xamarin_arch_trampoline + 105\n\t36  App.iOS                       0x000000010297ebee xamarin_x86_64_common_trampoline + 118\n\t37  QuickLook                           0x000000010ba7f823 -[QLPreviewController viewWillAppear:] + 398\n\t38  App.iOS                       0x000000010297ee8c xamarin_dyn_objc_msgSendSuper + 220\n\t39  ???                                 0x000000014e2389c4 0x0 + 5605919172\n  

I was trying to turn off the open in button in QLPreviewController. I asked a question on this thread for turning off open in. @Wenyan Zhang (Shanghai Wicresoft Co,.Ltd.) answered my question in here. And when I first tried it, I thought that the cause of this error was the action I did here. But the problem is not here. The problem seems to appear with QLPreviewController.

How can I fix this?
Thanks in advance.

Developer technologies | .NET | Xamarin
0 comments No comments
{count} votes

Accepted answer
  1. Wenyan Zhang (Shanghai Wicresoft Co,.Ltd.) 36,436 Reputation points Microsoft External Staff
    2023-01-09T06:42:27.56+00:00

    Hello,
    There are two ways to present a QLPreviewController, by calling presentViewController:animated:completion: from a presenting UIViewController, or pushing it into view using a UINavigationController.

    I test these two ways on iOS 16.0, 15.4. 14.5 13.7 simulators, it doesn't work on the simulators with iOS 15.4- iOS16.0, it is an issue of Apple, you can refer to the thread on Apple's forums- App crash on iOS16 when presenting… | Apple Developer Forums.

    And you can report this issue to Apple and have to prompt the users to update the system to iOS 16.0 above. (You can also report this at https://github.com/xamarin/xamarin-macios)

    Best Regards,
    Wenyan Zhang


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.


0 additional answers

Sort by: Most helpful

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.