如何从应用扩展启动父iOS应用

0dxa2lsx  于 2023-06-07  发布在  iOS
关注(0)|答案(9)|浏览(219)

有人知道如何从应用扩展的视图控制器启动父应用吗?
我只想从其应用扩展启动主应用。

hmtdttj4

hmtdttj41#

在WWDC会话Creating Extensions for iOS and OS X, Part 1中,在22分钟左右标记使用来自UIViewController的extensionContext的openURL:completionHandler:方法打开自定义URL方案

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

6rvt4ljy2#

Swift 3.1工作方案(iOS10测试):

  • 您需要为您的主机应用创建自己的URL Scheme *,然后将此函数添加到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
}
ercv8c1e

ercv8c1e3#

它在我当前的工作应用程序中使用操作扩展
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()
    }
}

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

u2nhd7ah

u2nhd7ah4#

我在这里问了一个类似的问题: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];

1.使用UIDocumentInteractionController和自定义文件扩展名类型提供指向包含应用程序的链接(仅限于包含应用程序)
1.启动一个“假”NSURL会话以获得以下功能:在iOS中,如果您的扩展在后台任务完成时未运行,则系统会在后台启动包含应用程序的应用程序并调用应用程序:handleEventsForBackgroundURLSession:completionHandler:app委托方法。
第一个可能是你最好的选择。

hmmo2u0o

hmmo2u0o5#

文档非常清楚地说明了您可以在Today扩展中使用extensionContext openURL。言外之意,openURL只能在Today异常中使用,我们的经验证明了这一点--我也不能让它在Share扩展中工作。
我很有兴趣看看这些变通方法是否被苹果的审查过程所接受。我很怀疑如果苹果想让它工作,他们很容易允许它。
Apple允许任何Today小部件使用openURL:completionHandler:方法打开小部件自己的包含应用程序。
如果您使用此方法从Today Widget中打开其他应用,则您的App Store提交可能需要进行额外审查,以确保符合Today Widget的意图。
我敢肯定这第二段是在Launcher被接受,拒绝,然后后来批准销售后添加的。

qxsslcnc

qxsslcnc6#

下面是另一种方法:

  1. Step 1 from here
    1.选择扩展目标并转到其Build Settings。将Require Only App-Extension Safe API设置为NO
    1.使用UIApplication.shared.openURL(URL(string:"openPdf://")!),就像你通常在扩展外打开url一样。
    请注意,您将收到 *'openURL'在iOS 10.0中已弃用警告 *。因此,这似乎不能保证它在未来的工作。
    考虑使用本地通知来唤醒主机应用程序,而不是这样。
ds97pgxw

ds97pgxw7#

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

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

gijlo24d8#

以下是**工作解决方案(在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)
    }

}
p5cysglq

p5cysglq9#

我在我的扩展中使用以下代码来打开带有自定义方案URL的主应用程序:

fileprivate func openUrl(url: URL?) {
    let selector = sel_registerName("openURL:")
    var responder = self as UIResponder?
    while let r = responder, !r.responds(to: selector) {
        responder = r.next
    }
    _ = responder?.perform(selector, with: url)
}

请确保在调用此函数之前有足够的时间加载扩展。

相关问题