3

I've tried [self.extensionContext openURL:completion], but my app crashed. I heard some extensions can't use this method, can iMessage extensions?

By the way, can host app activate its iMessage extension?

Andrew
  • 15,357
  • 6
  • 66
  • 101
Maize
  • 109
  • 2
  • 8
  • Check this answer [Open My application from my keyboard extension in swift 3.0](https://stackoverflow.com/a/44718613/2150318) – Kamal Upasena Jul 05 '17 at 06:52

5 Answers5

6

Share Extensions and Action Extensions are not designed to function as app launchers.

App Extension Programming Guide

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.

The extension displays a user interface, performs some work, and, if appropriate for the extension’s purpose, returns data to the host.

There is 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. "

enter image description here

A work around derived from this SO question.

Working solution (tested on iOS 9.2) for Keyboard Extension.

This category adds special method for access to hidden sharedApplication object and then call openURL: on it. (Of course then you have to use openURL: method with your app scheme.)

// Valentin Shergin

extension UIInputViewController {

func openURL(url: NSURL) -> Bool {
    do {
        let application = try self.sharedApplication()
        return application.performSelector("openURL:", withObject: url) != nil
    }
    catch {
        return false
    }
}

func sharedApplication() throws -> UIApplication {
    var responder: UIResponder? = self
    while responder != nil {
        if let application = responder as? UIApplication {
            return application
        }

        responder = responder?.nextResponder()
    }

    throw NSError(domain: "UIInputViewController+sharedApplication.swift", code: 1, userInfo: nil)
}

}
Community
  • 1
  • 1
Edison
  • 11,881
  • 5
  • 42
  • 50
  • Thanks, so i can not use `openURL:completion` in my messages extension? – Maize Jul 12 '16 at 04:03
  • Not the completion but you can use that very short extension to access the hidden `sharedApplication` object and then call `openURL` on it. I just updated my answer. – Edison Jul 12 '16 at 04:07
  • Has anyone gotten an app that uses this extension (or the swift3 version from @vmeyer) into the app store? It's all well and good if it's technically possible, but if apple disallows the app because of it, it doesn't really help. – SuperDuperTango Dec 08 '16 at 07:18
  • Does this allow people to open urls from message extensions? – blue Dec 25 '16 at 22:59
2

self.extensionContext?.open(url, completionHandler: nil) doesn't work in my iMessage extension.

tymac answer is correct, however openURL has been moved to open in Swift 3.

I found a simpler solution in this thread : openURL not work in Action Extension

extension UIViewController {

  func openURL(url: URL) {
    var responder = self as UIResponder?

    while (responder != nil){
      if responder?.responds(to: Selector("openURL:")) == true{
        responder?.perform(Selector("openURL:"), with: url)
      }
      responder = responder!.next
    }
  }

}
Community
  • 1
  • 1
vmeyer
  • 1,998
  • 21
  • 23
0

This is apparently not working in Seed 2 but should be fixed in Seed 3.

https://forums.developer.apple.com/message/153441#153441

Maize
  • 109
  • 2
  • 8
  • It's not that it's not working. They're not meant to function in this manner. This should not be the accepted answer. – MattWright Jul 30 '16 at 22:09
  • 1
    `i just did a test. now you can open host app from iMessage extension on beta 4` – Maize Aug 10 '16 at 06:54
-1

This works fine for me:

NSString *customURL = @"myHostAppName://";

    if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:customURL]]) {
        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:customURL]];
    } else {

        UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"URL error" message:[NSString stringWithFormat:@"No custom URL defined for %@", customURL] preferredStyle:UIAlertControllerStyleAlert];

        UIAlertAction* ok = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil];
        [alertController addAction:ok];

        [self presentViewController:alertController animated:YES completion:nil];
    }

Remember re-install the host app again.

Take in consideration How to open our app from iMessage

Community
  • 1
  • 1
jose920405
  • 7,982
  • 6
  • 45
  • 71
-2
[self.extensionContext openURL:YOUR_NSURL completionHandler:nil];

it would be nice if you can pass deeplinks to open specific screen in app

Jay
  • 19,649
  • 38
  • 121
  • 184