Access extensionContext from a submitted view controller

I tried to create a custom view controller to extend sharing.

A difficult situation arises when I present another top view controller of the original view controller that was installed on MainInterface.storyboard . This presented view controller is built into the navigation controller (this is its root view controller).

I did a check on the ViewController view

 (lldb) po [self presentingViewController] <_UIViewServiceViewControllerOperator: 0x7a978000> (lldb) po [[self presentingViewController] extensionContext] nil 

So, the extension context is nil at this point. I could access extensionContext by passing it from the current ViewController view to the presented control controller.

But I found that this behavior is a bit strange. Is an application extension designed to access only one level of the view manager hierarchy?

+6
source share
3 answers

If you intend to use more than one view controller in the extension storyboard, you will need to pass a link to the extensionContext original view controller to the view controller, which will ultimately be responsible for completing the extension request. In the initial view controller:

 override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { let destination = segue.destinationViewController as! FinalViewController destination.originalExtensionContext = self.extensionContext } 

And in your final controller:

 @IBAction func dismissController(sender: UIButton!) { dismissViewControllerAnimated(true) { () -> Void in self.originalExtensionContext.completeRequestReturningItems(self.originalExtensionContext.inputItems, completionHandler: nil) } 

Note that you need to create a property with a unique name for the original extension context, since extensionContext already exists as the property name in the superclass of UIViewController . You cannot pass an existing extensionContext to the UIViewController extensionContext property, as it is a read-only attribute.

+5
source

The view controller represented by the view controller should not have problems using the parent extension. Having looked at the documentation:

The view controller can check this property to see if it participates in an extension request. If no extension context is set for the current view controller, the system walks up the view controller hierarchy to find a parent view controller that has a non nil extensionContext value.

Therefore, if you can be sure that your root view controller really has extensionContext , any view controller represented by this view controller should have access to it simply through its own extensionContext property.

Note. If this is not the behavior you are observing, it could be a bug with the SDK, and I would recommend filing a radar.

+1
source

Although this is not the best approach for clean code and architecture, it is quite convenient:

In the root controller extensionContext where extensionContext exists:

 final class ShareRootViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() NSExtensionContext.shared = self.extensionContext } } extension NSExtensionContext { fileprivate(set) static var shared: NSExtensionContext! } 

In any other view controller:

 let context = NSExtensionContext.shared 
0
source

Source: https://habr.com/ru/post/1201316/


All Articles