如何从其App Extension启动父iOS应用程序

有没有人知道如何从应用扩展程序的视图控制器启动父应用程序?

我只想从其应用扩展程序启动主应用程序。

在WWDC会话中为iOS和OS X创建扩展,第1部分大约22分钟标记,使用来自UIViewController的extensionContext的openURL:completionHandler:方法来打开自定义URL方案

 [self.extensionContext openURL:[NSURL URLWithString:@"your-app-custom-url-scheme://your-internal-url"] completionHandler:nil]; 

我在这里问了一个类似的问题: 与Share扩展中的/包含应用程序进行通信 。 基本上,你可以做几件事。

  1. 使用UIWebView的loadRequest webView加载包含应用程序URL的NSURL请求。 例如,

     NSURL *url = [NSURL URLWithString:@"myurl"]; NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url]; [self.webView loadRequest:request]; 
  2. 使用UIDocumentInteractionController和自定义文件扩展名类型提供指向包含应用程序的链接(仅包含您的应用程序)

  3. 启动“假”NSURL会话以获得以下function:在iOS中,如果后台任务完成时您的扩展未运行,系统将在后台启动包含应用程序并调用应用程序:handleEventsForBackgroundURLSession:completionHandler:app delegate method 。

第一个可能是你最好的选择。

文档非常清楚地表明您可以在Today扩展中使用extensionContext openURL。 通过暗示,openURL只能用于今天的例外,我们的经validation明这是真的 – 我也无法在Share扩展中使用它。

我很想知道Apple的审核流程是否接受了这些工作中的任何一个。 我对此表示怀疑。 如果Apple希望它能够运行,那么它们就足够容易了。

Apple允许任何Today小部件使用openURL:completionHandler:方法打开小部件自己的包含应用程序。

如果您使用此方法从“今日”窗口小部件打开其他应用程序,则您的App Store提交可能需要进行额外审核,以确保符合“今日”窗口小部件的意图。

我确定第二段是在Launcher被接受,被拒绝后被添加,然后被批准出售。

这是工作解决方案(在iOS 9.2上测试) ,至少对于键盘扩展。 此类别添加了访问隐藏的sharedApplication对象的特殊方法,然后在其上调用openURL: sharedApplication (当然,您必须使用openURL:方法与您的应用程序方案。)

 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) } } 

Swift 3.1中的工作解决方案(在iOS10中测试):

您需要为主机应用程序创建自己的URL Scheme ,然后将此函数添加到ViewController并使用openURL("myScheme://myIdentifier")调用它openURL("myScheme://myIdentifier")

 // Function must be named exactly like this so a selector can be found by the compiler! // Anyway - it's another selector in another instance that would be "performed" instead. func openURL(_ url: URL) -> Bool { var responder: UIResponder? = self while responder != nil { if let application = responder as? UIApplication { return application.perform(#selector(openURL(_:)), with: url) != nil } responder = responder?.next } return false }