Perform action in host app from Today extension(Widget) Without opening app ios Perform action in host app from Today extension(Widget) Without opening app ios ios ios

Perform action in host app from Today extension(Widget) Without opening app ios


Use MMWormhole (or its new and unofficial Swift version, just Wormhole). It's very simple.

In the app's view controller:

override func viewDidLoad() {    super.viewDidLoad()    // Do any additional setup after loading the view, typically from a nib.    let wormhole = MMWormhole(applicationGroupIdentifier: "group.test.TodayExtensionSharingDefaults",                              optionalDirectory: "TodayExtensionSharingDefaults")    wormhole.listenForMessage(withIdentifier: "togglePlayPause") { [weak self] _ in        guard let controller = self else { return }        controller.btnValue.isSelected = controller.btnValue.isSelected    }}

In the extension:

override func viewDidLoad() {    super.viewDidLoad()    // Do any additional setup after loading the view from its nib.    self.wormhole = MMWormhole(applicationGroupIdentifier: "group.test.TodayExtensionSharingDefaults", optionalDirectory: "TodayExtensionSharingDefaults")}@IBAction func onPlayPause(_ sender: UIButton) {    guard let wormhole = self.wormhole else { extensionContext?.openURL(NSURL(string: "foo://startPlaying")!, completionHandler: nil) } // Throw error here instead of return, since somehow this function was called before viewDidLoad (or something else went horribly wrong)    wormhole.passMessageObject(nil, identifier: "togglePlayPause")}

Declare foo:// (or whatever else you use) in Xcode's Document Types section, under URLs, then implement application(_:open:options:) in your AppDelegate so that the app starts playing music when the URL passed is foo://startPlaying.

how to add URL to Xcode


  1. Create Custom URL Sceheme

  2. Check groups data.(are you setting correct or not)

  3. Whenever you click on button, the host app will get called from Appdelegate, UIApplication delegate

    func application(_ application: UIApplication, open urls: URL, sourceApplication: String?, annotation: Any) -> Bool {        let obj = urls.absoluteString.components(separatedBy: "://")[1]        NotificationCenter.default.post(name: widgetNotificationName, object: obj)        print("App delegate")        return true    }
  4. Fire your notification from there then observe it anywhere in your hostapp.

    Widget Button action code

    @IBAction func doActionMethod(_ sender: AnyObject) {    let button = (sender as! UIButton)    var dailyThanthi = ""    switch button.tag {    case 0:        dailyThanthi = "DailyThanthi://h"    case 1:        dailyThanthi = "DailyThanthi://c"    case 2:        dailyThanthi = "DailyThanthi://j"        //        case 3:        //            dailyThanthi = "DailyThanthi://s"        //        case 4:        //            dailyThanthi = "DailyThanthi://s"    default:        break    }    let pjURL = NSURL(string: dailyThanthi)!    self.extensionContext!.open(pjURL as URL, completionHandler: nil)}
  5. Check out custom url type:https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/Inter-AppCommunication/Inter-AppCommunication.html

  6. Note:

    There is no direct communication between an app extension and its containing app; typically, the containing app isn’t even running while a contained extension is running. An app extension’s containing app and the host app don’t communicate at all.

    In a typical request/response transaction, the system opens an app extension on behalf of a host app, conveying data in an extension context provided by the host. The extension displays a user interface, performs some work, and, if appropriate for the extension’s purpose, returns data to the host.

    The dotted line in Figure 2-2 represents the limited interaction available between an app extension and its containing app. A Today widget (and no other app extension type) can ask the system to open its containing app by calling the openURL:completionHandler: method of the NSExtensionContext class. As indicated by the Read/Write arrows in Figure 2-3, any app extension and its containing app can access shared data in a privately defined shared container. The full vocabulary of communication between an extension, its host app, and its containing app is shown in simple form in Figure 2-3.

    https://developer.apple.com/library/content/documentation/General/Conceptual/ExtensibilityPG/ExtensionOverview.html