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

时间:2014-09-08 15:12:25

标签: ios ios-app-extension today-extension share-extension

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

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

7 个答案:

答案 0 :(得分:9)

在大约22分钟的WWDC会话中Creating Extensions for iOS and OS X, Part 1标记使用来自UIViewController extensionContextopenURL:completionHandler:方法打开custom URL scheme

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

答案 1 :(得分:2)

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

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

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

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

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

答案 2 :(得分:2)

它正在使用动作扩展在我当前的工作应用中正常工作

1-在父应用程序plist中添加自定义网址,例如 enter image description here

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是应显示的View控制器的类名

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

我希望一切正常,也可以在扩展应用和父应用之间共享数据

答案 3 :(得分:1)

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

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

  

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

     

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

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

答案 4 :(得分: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)
    }

}

答案 5 :(得分:1)

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

您需要为您的主机应用创建自己的网址方案,然后将此功能添加到您的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
}

答案 6 :(得分:1)

这是另一种方法:

  1. Step 1 from here
  2. 选择扩展目标,然后转到其Build Settings。将Require Only App-Extension Safe API设置为NO
  3. 使用UIApplication.shared.openURL(URL(string:"openPdf://")!),就像您通常在扩展名之外使用它来打开url一样。

请注意,您会收到'openURL'在iOS 10.0警告中已弃用。因此,似乎不能保证将来可以正常工作。

考虑使用本地通知来代替此方法来唤醒主机应用。