18

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

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

4

8 回答 8

10

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

[self.extensionContext openURL:[NSURL URLWithString:@"your-app-custom-url-scheme://your-internal-url"]
             completionHandler:nil];
于 2014-09-11T10:52:21.843 回答
7

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

您需要为您的主机应用程序创建自己的 URL 方案,然后将此函数添加到您的 ViewController 并调用它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
}
于 2017-06-12T12:19:19.360 回答
5

它正在使用操作扩展在我当前的工作应用程序中工作

1-在父应用 plist 添加自定义 URL,如 在此处输入图像描述

2-在扩展视图控制器中添加这两个功能

func openURL(url: NSURL) -> Bool {
    do {
        let application = try self.sharedApplication()
        return application.performSelector(inBackground: "openURL:", with: 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?.next
    }

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

3-在您的按钮操作或您想做的地方调用此函数

self.openURL(url: NSURL(string:"openPdf://HomeVC")!)

这里 homevc 是应该显示的视图控制器的类名

4-在您的应用程序委托中实现类似的方法

  func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
    let urlPath : String = url.absoluteString
    print(urlPath)
    if urlPath.contains("HomeVC"){
        //here go to firstViewController view controller
        self.window = UIWindow(frame: UIScreen.main.bounds)

        let storyboard = UIStoryboard(name: "Main", bundle: nil)

        let initialViewController = storyboard.instantiateViewController(withIdentifier: "homeVC")

        self.window?.rootViewController = initialViewController
        self.window?.makeKeyAndVisible()
    }
}

我希望能正常工作,也可以在扩展应用程序和父应用程序之间共享数据

于 2020-02-20T12:19:44.007 回答
2

我在这里问了一个类似的问题:Communicating with/opening Containing app from Share extension。基本上,你可以做几件事。

  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 会话以获得以下功能: 在 iOS 中,如果您的扩展在后台任务完成时没有运行,系统会在后台启动您的包含应用程序并调用 application:handleEventsForBackgroundURLSession:completionHandler:app 委托方法.

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

于 2014-09-09T17:02:44.493 回答
2

该文档非常清楚地说明您可以在 Today 扩展中使用 extensionContext openURL。暗示,openURL 只能在 Today 异常中使用,我们的经验证明这是真的——我也无法在 Share 扩展中使用它。

我很想知道这些变通办法是否被 Apple 的审查流程接受。我对此表示怀疑。如果苹果想让它工作,他们很容易允许它。

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

如果您使用此方法从 Today 小部件打开其他应用程序,您的 App Store 提交可能需要额外审查,以确保符合 Today 小部件的意图。

我确信这第二段是在 Launcher 被接受、拒绝和后来批准出售之后添加的。

于 2015-05-07T15:34:29.527 回答
2

这是另一种方法:

  1. 从这里开始第 1 步
  2. 选择扩展目标并转到其Build Settings. 设置Require Only App-Extension Safe APINO
  3. 像往常一样使用UIApplication.shared.openURL(URL(string:"openPdf://")!)外部扩展来打开网址。

请注意,您将得到'openURL' 在 iOS 10.0 警告中已弃用。所以这看起来不能保证将来会起作用。

考虑使用本地通知来唤醒主机应用程序而不是这个。

于 2020-07-08T17:42:11.720 回答
1

这是至少针对键盘扩展的工作解决方案(在 iOS 9.2 上测试) 。该类别添加了访问隐藏sharedApplication对象然后调用openURL:它的特殊方法。(当然,你必须在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)
    }

}
于 2015-12-23T00:31:56.513 回答
0

这是ios 14 和 xcode 13Valentin Shergin's的解决方案

extension KeyboardViewController{
    func openURL(url: NSURL) -> Bool {
            do {
                let application = try self.sharedApplication()
                return (application.perform("openURL:", with: 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?.next
            }

            throw NSError(domain: "UIInputViewController+sharedApplication.swift", code: 1, userInfo: nil)
        }
}
于 2021-09-28T11:00:00.390 回答