This works for iOS8 & iOS9 for 3rd party apps AND System Apps!
It's not pretty but it works.
Can anyone tell me if this will pass App Review? Not sure as I'm referring to a class name which is not publicly accessible (_UIDocumentActivityViewController).
This is Swift 2.2!
NSObject Extension to get a string of the class name:
extension NSObject {
var theClassName: String {
return NSStringFromClass(self.dynamicType)
}
}
Your Viewcontroller where you're calling the UIDocumentInteractionController from:
var appOpened = false
var presentedVCMonitoringTimer: NSTimer!
var docController: UIDocumentInteractionController!
func openDocController() {
docController = UIDocumentInteractionController(URL: yourURL!)
docController.UTI = "your.UTI"
docController.delegate = self
docController.presentOptionsMenuFromRect(CGRectZero, inView: self.view, animated: true)
// Check the class of the presentedViewController every 2 seconds
presentedVCMonitoringTimer = NSTimer.scheduledTimerWithTimeInterval(2, target: self, selector: #selector(self.checkPresentedVC), userInfo: nil, repeats: true)
}
func checkPresentedVC() {
if let navVC = UIApplication.sharedApplication().keyWindow?.rootViewController as? UINavigationController {
print(navVC.presentedViewController?.theClassName)
if navVC.presentedViewController != nil && (navVC.presentedViewController?.theClassName)! != "_UIDocumentActivityViewController" && (navVC.presentedViewController?.theClassName)! != self.theClassName {
// A system App was chosen from the 'Open In' dialog
// The presented ViewController is not the DocumentInteractionController (anymore) and it's not this viewcontroller anymore (could be for example the MFMailComposeViewController if the user chose the mail app)
appOpened = true
presentedVCMonitoringTimer?.invalidate()
presentedVCMonitoringTimer = nil
}
}
}
func documentInteractionControllerDidDismissOptionsMenu(controller: UIDocumentInteractionController) {
print("dismissedOptionsMenu")
presentedVCMonitoringTimer?.invalidate()
presentedVCMonitoringTimer = nil
if appOpened {
// Do your thing. The cancel button was not pressed
appOpened = false
}
else {
// Do your thing. The cancel button was pressed
}
}
func documentInteractionController(controller: UIDocumentInteractionController, willBeginSendingToApplication application: String?) {
// A third party app was chosen from the 'Open In' menu.
appOpened = true
presentedVCMonitoringTimer?.invalidate()
presentedVCMonitoringTimer = nil
}
DidDismissOpenInMenu
is called beforeDidEndSendingToApplication
. You need to useWillBeginSendingToApplication
instead. – Weisman