A UIDocumentInteractionController is used to enable the sharing of documents between your app and other apps installed on a user's device. It is simple to set up as long as you remember two rules:
- Always make the UIDocumentInteractionController instance a class (type) property. If you only retain a reference to the controller for the life of the method that is triggered by the button press your app will crash.
- Configure the UIDocumentInteractionController before the button calling the method is pressed so that there is not a wait in which the app is waiting for the popover to appear.
Note: If you're dealing with a document that is being continuously saved to the same URL, then there is no harm in instantiating early. And even if the user moves the document to a new URL, you can simply update the UIDocumentInteractionController URL property. The only fee you are paying is the memory required to hold the instance and you will likely find this is a small price for an enhanced user experience.
In code
So here is a rather contrived example implementing these two rules. It assumes you have a file called MyFile.txt in the app bundle and that you have a UIBarButtonItem wired up to the controller called actionButton, and that this button is also wired up to the shareDoc() method:class ViewController: UIViewController { // UIDocumentInteractionController instance is a class property var docController:UIDocumentInteractionController! // called when bar button item is pressed @IBAction func shareDoc(sender: AnyObject) { // present UIDocumentInteractionController docController.presentOptionsMenuFromBarButtonItem(sender as! UIBarButtonItem, animated: true) } override func viewDidLoad() { super.viewDidLoad() // retrieve URL to file in main bundle let fileURL = NSBundle.mainBundle().URLForResource("MyFile", withExtension: "txt")! // Instantiate the interaction controller self.docController = UIDocumentInteractionController(URL: fileURL) } }With the two rules in place there's not much to the actual presentation of the controller. But since the popover presentation is asynchronous, it is worth outlining how to take the instantiation of the UIDocumentInterationController off the main thread as well.
class ViewController: UIViewController { // UIDocumentInteractionController instance is a class property var docController:UIDocumentInteractionController! // we're going to disable action button while controller is instantiated @IBOutlet weak var actionButton: UIBarButtonItem! // called when bar button item is pressed @IBAction func shareDoc(sender: AnyObject) { // present UIDocumentInteractionController docController.presentOptionsMenuFromBarButtonItem(sender as! UIBarButtonItem, animated: true) } override func viewDidLoad() { super.viewDidLoad() // disable action button actionButton.enabled = false // Set priority for dispatch let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT // take instantiation off the main thread dispatch_async(dispatch_get_global_queue(priority, 0)) { [unowned self] in // retrieve URL to file in main bundle let fileURL = NSBundle.mainBundle().URLForResource("MyFile", withExtension: "txt")! // Instantiate the interaction controller self.docController = UIDocumentInteractionController(URL: fileURL) dispatch_async(dispatch_get_main_queue()) { // re-enable action button [unowned self] in self.actionButton.enabled = true } } } }In the example you'll be lucky to catch the button in a disabled state but the technique might prove useful when seeking an opportune moment to prepare your UIDocumentInteractionController where lag might be more noticeable. (It might also be worth considering this asynchronous, or at least preprepared, approach when passing NSURLs to a UIActivityViewController if you find any slow downs there.)
Conclusion
A UIDocumentInteractionController performs a similar role to a UIActivityViewController without relying on the existence of extensions for the apps your user might wish to share documents with. It also works with the assumption that the user will commonly be dealing with documents rather than performing an activity or action like copy and paste or sending a tweet.
Although there is cross-over between the two types of sharing – using UIDocumentInteractionController and UIActivityViewController – they do not entirely eclipse one another. It is therefore important to be aware of the existence of both classes and their roles, and I would encourage you now to dig deeper into the UIDocumentInteractionController and the accompanying UIDocumentInteractionControllerDelegate protocol.
Thank you very much! Very useful.
ReplyDelete