I'm trying to display a UIDocumentMenuViewController from the view model in a Xamarin.Forms application. The UIDocumentMenuViewController displays correctly, but when I select a provider the UIDocumentPickerViewController displays a black screen. The view hierarchy looks the same as for the Xamarin DocPicker sample. Am I using the right view controller here?
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using UIKit;
using Foundation;
using MobileCoreServices;
using Oban.Mobile.Services;
namespace Oban.Mobile.iOS.Services
{
public class FilePicker : IFilePicker
{
public async Task<ImportedFile> ImportFile(List<string> contentTypes)
{
var ubiq = await Task.Run(() => NSFileManager.DefaultManager.GetUrlForUbiquityContainer(null));
if (ubiq == null)
{
throw new Exception("iCloud not available");
}
TaskCompletionSource<ImportedFile> tcs = new TaskCompletionSource<ImportedFile>();
var allowedUTIs = new string[] { UTType.UTF8PlainText,
UTType.PlainText,
UTType.RTF,
UTType.PNG,
UTType.Text,
UTType.PDF,
UTType.Image };
var activeController = UIControllerHelper.FindActiveViewController();
UIDocumentMenuViewController pickerMenu = new UIDocumentMenuViewController(allowedUTIs, UIDocumentPickerMode.Import);
pickerMenu.WasCancelled += (sender, args) => tcs.SetResult(null);
pickerMenu.DidPickDocumentPicker += (sender, args) =>
{
args.DocumentPicker.WasCancelled += (docSender, docArgs) => tcs.SetResult(null);
args.DocumentPicker.DidPickDocument += (docSender, docArgs) =>
{
ImportedFile file = null;
try
{
var securityEnabled = docArgs.Url.StartAccessingSecurityScopedResource();
var data = NSData.FromUrl(docArgs.Url);
file = new ImportedFile(docArgs.Url.LastPathComponent, data.ToArray());
tcs.SetResult(file);
}
catch (Exception excp)
{
tcs.SetException(excp);
}
finally
{
docArgs.Url.StopAccessingSecurityScopedResource();
}
};
args.DocumentPicker.View.TranslatesAutoresizingMaskIntoConstraints = false;
args.DocumentPicker.View.BackgroundColor = UIColor.White;
args.DocumentPicker.ModalPresentationStyle = UIModalPresentationStyle.FullScreen;
args.DocumentPicker.View.Frame = activeController.View.Frame;
args.DocumentPicker.View.Bounds = activeController.View.Bounds;
activeController.PresentViewController(args.DocumentPicker, true, null);
};
pickerMenu.ModalPresentationStyle = UIModalPresentationStyle.Popover;
pickerMenu.View.TranslatesAutoresizingMaskIntoConstraints = false;
activeController.PresentViewController(pickerMenu, true, null);
UIPopoverPresentationController presentationPopover = pickerMenu.PopoverPresentationController;
if (presentationPopover != null)
{
presentationPopover.SourceView = activeController.View;
presentationPopover.PermittedArrowDirections = UIPopoverArrowDirection.Down;
presentationPopover.SourceRect = activeController.View.Frame;
}
return await tcs.Task;
}
}
public static class UIControllerHelper
{
public static UIViewController FindActiveViewController()
{
UIViewController vc = UIApplication.SharedApplication.KeyWindow.RootViewController;
while (vc.PresentedViewController != null)
{
vc = vc.PresentedViewController;
}
return vc;
}
}
public class ImportedFile
{
public string FileName { get; private set; }
public byte[] Content { get; private set; }
public ImportedFile(string fileName, byte[] content)
{
this.FileName = fileName;
this.Content = content;
}
}
public interface IFilePicker
{
Task<ImportedFile> ImportFile(List<string> contentTypes);
}
}