app crash on show UIDocumentMenuViewController from UIWebView

Hello, I am developing an app that allows access to different websites and shows the answer in a UIWebview. I have found that when trying to load a file from a web (html loaded in the UIWebview) using a file input, the app breaks in IOS13 and returns the following error:


*** Terminating app due to uncaught exception 'NSGenericException', reason: 'Your application has presented a UIDocumentMenuViewController (<UIDocumentMenuViewController: 0x7f7fbb021ea0>). In its current trait environment, the modalPresentationStyle of a UIDocumentMenuViewController with this style is UIModalPresentationPopover. You must provide location information for this popover through the view controller's popoverPresentationController. You must provide either a sourceView and sourceRect or a barButtonItem.  If this information is not known when you present the view controller, you may provide it in the UIPopoverPresentationControllerDelegate method -prepareForPopoverPresentation.'


I have been looking for solutions and I have found the solution that I show below to control the presentation of the UIDocumentMenuViewController should work, but it still gives the same error, since it does not enter the prepareForPopoverPresentation method


override open func present(_ viewControllerToPresent: UIViewController, animated flag: Bool, completion: (() -> Void)? = nil) {
  if #available(iOS 13, *), viewControllerToPresent is UIDocumentMenuViewController {
    viewControllerToPresent.popoverPresentationController?.delegate = self
  }
  super.present(viewControllerToPresent, animated: flag, completion: completion)
  }

func prepareForPopoverPresentation(_ popoverPresentationController: UIPopoverPresentationController) {
  popoverPresentationController.sourceView = self.view
  }


What am I doing wrong so it doesn't work?

Replies

I am pretty sure, the OP would have found the answer for the above problem that he is facing. This is for folks like me who were trying to solve the same problem and looking for a solution online.
  1. Whatever the OP has mentioned in the sample code should work fine.

  2. For some reason, if your app has highly complex logic and if it doesn't trigger the present(_viewControllerToPresent...), its better to write an extension on UINavigationController and put the logic there.

Code Block
extension UINavigationController {
override open func present(_ viewControllerToPresent: UIViewController, animated flag: Bool, completion: (() -> Void)? = nil) {
if #available(iOS 13, *), let webKitVC = topViewController as? WebKitViewController {
viewControllerToPresent.popoverPresentationController?.delegate = webKitVC
}
super.present(viewControllerToPresent, animated: flag, completion: completion)
}
}