14

I am trying to create a custom view controller to be used with a share extension. Everything works, but I don't know how to dismiss the custom view controller. Basically I launch my share extension from safari and want to completely dismiss this and return back to the safari view. I know this should not be hard, but I am new to share extensions. Below is my base code. Thanks. Bob

//
//  ShareViewController.swift
//  ShareExtension


import UIKit
import Social
import MobileCoreServices

class ShareViewController: UIViewController {
    private var url: NSURL?


    @IBAction func backButton(_ sender: Any) {
        print("back button pressed")

       self.dismiss(animated: true, completion: nil)
    }


    override func viewDidLoad()  {
        super.viewDidLoad()
    }


    private func getURL() {
        let extensionItem = extensionContext?.inputItems.first as! NSExtensionItem
        let itemProvider = extensionItem.attachments?.first as! NSItemProvider
        let propertyList = String(kUTTypePropertyList)
        if itemProvider.hasItemConformingToTypeIdentifier(propertyList) {
            itemProvider.loadItem(forTypeIdentifier: propertyList, options: nil, completionHandler: { (item, error) -> Void in
                guard let dictionary = item as? NSDictionary else { return }
                OperationQueue.main.addOperation {
                    if let results = dictionary[NSExtensionJavaScriptPreprocessingResultsKey] as? NSDictionary,
                        let urlString = results["URL"] as? String,
                        let url = NSURL(string: urlString) {
                        self.url = url
                    }
                }
            })
        } else {
            print("error")
        }
    }
}
Robert Marlan
  • 369
  • 2
  • 11

2 Answers2

41

You should end your sharing extensions work with one of these two calls:

self.extensionContext!.completeRequestReturningItems(nil, completionHandler: nil)

self.extensionContext!.cancelRequestWithError(NSError())

Apples share extension docs

updated for swift 4:

self.extensionContext!.completeRequest(returningItems: nil, completionHandler: nil)

self.extensionContext!.cancelRequest(withError:NSError())
OliverD
  • 864
  • 7
  • 8
  • 2
    For Xcode 8.3 I had to modify to: self.extensionContext!.completeRequest(returningItems: nil, completionHandler: nil) - but that works! Thanks. I appreciate the help. – Robert Marlan Apr 28 '17 at 03:32
  • Sorry, forgot to update code for swift 3, your are right – OliverD Apr 28 '17 at 03:37
  • 1
    @OliverM after adding this lines still is not working – Satheeshkumar Naidu Apr 24 '19 at 06:03
  • The key is to call completeRequestReturningItems before dismissing the custom view controller – massimobio Jan 12 '20 at 18:49
  • 8
    `NSError()` crashes on runtime (swift5). You should return `NSError(domain: "com.domain.name", code: 0, userInfo: nil)` instead – Lirik Jan 24 '20 at 15:11
  • 4
    **DO NOT** pass an empty NSError() instance to `cancelRequest` method or it will lead to EXC_BAD_INSTRUCTION crash. You can use main bundle's identifier as a domain: `NSError(domain: Bundle.main.bundleIdentifier!, code: 0)` – Igor Kharakhordin Mar 19 '20 at 07:03
4

For those who are trying to do this from viewDidLoad, you need to set a small timer, otherwise it won't work:

override func viewDidLoad() {
    super.viewDidLoad()
    Timer.scheduledTimer(timeInterval: 0.2, target: self, selector: #selector(self.didSelectPost), userInfo: nil, repeats: false)
  }
Lenka Pitonakova
  • 979
  • 12
  • 14