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:
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.