有人知道如何从应用程序扩展的视图控制器启动父应用程序吗?
我只想从应用程序扩展启动主应用程序。
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
}
在 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];
它正在我当前的工作应用程序中使用操作扩展
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()
}
}
我希望能正常工作,还可以在扩展应用程序和父应用程序之间共享数据
这是
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)
}
}
我在这里问了类似的问题:与共享扩展程序通信/打开包含应用程序。基本上,您可以做几件事。
使用 UIWebView 的 loadRequest webView 加载包含应用程序 URL 的 NSURL 请求。例如,
NSURL *url = [NSURL URLWithString:@"myurl"];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
[self.webView loadRequest:request];
使用 UIDocumentInteractionController 和自定义文件扩展类型来提供指向您的包含应用程序的链接(并且仅包含您的包含应用程序)
启动“假”NSURL 会话以获得以下功能:在 iOS 中,如果后台任务完成时您的扩展程序未运行,系统会在后台启动您的包含应用程序并调用 application:handleEventsForBackgroundURLSession:completionHandler: app委托方法。
第一个可能是您最好的选择。
文档非常清楚地说明您可以在 Today 扩展中使用 extensionContext openURL。 言外之意,openURL 只能在 Today 例外中使用,我们的经验证明这是真的——我也无法在共享扩展中使用它。
我有兴趣了解 Apple 的审核流程是否接受这些变通办法。 我对此表示怀疑。 如果苹果希望它发挥作用,他们很容易允许它。
Apple 允许任何 Today 小部件使用 openURL:completionHandler: 打开小部件自己的包含应用程序的方法。
如果您使用此方法从“今日”小部件打开其他应用程序, 您提交的 App Store 可能需要额外审核以确保 符合今日小部件的意图。
我确定第二段是在 Launcher 被接受、拒绝然后批准销售之后添加的。
这是工作解决方案(在 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)
}
}
这是另一种方法:
Build Settings
。将 Require Only App-Extension Safe API
设置为 NO
。UIApplication.shared.openURL(URL(string:"openPdf://")!)
就像您通常在扩展程序之外打开网址一样。请注意,您将收到 “openURL”在 iOS 10.0 中已弃用警告。所以这看起来并不能保证它将来会起作用。
考虑使用本地通知来唤醒主机应用程序而不是这个。
我在扩展程序中使用此代码通过自定义方案 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)
}
在调用此函数之前,请确保扩展程序有足够的时间来加载。
在 Xcode-16.1、iOS-18 中测试。
转到父应用程序的目标 -> 信息。
向下滚动并添加 URL 类型
在这里,标识符应该是您的父应用程序的包标识符。
现在添加以下代码以从应用程序扩展
打开父应用程序func openParentApp() {
if let url = URL(string: "openmybestappfromkeyboard://") {
var responder: UIResponder? = self
while responder != nil {
if let application = responder as? UIApplication {
application.open(url)
break
}
responder = responder?.next
}
}
}
现在,转到父应用程序的 AppDelegate 并添加以下代码。
func application(_ application: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool {
if url.scheme == "openmybestappfromkeyboard" {
return true
} else {
return false
}
}