有谁知道如何从应用程序扩展的视图控制器中启动父应用程序?
我只想从应用程序扩展中启动主应用程序。
有谁知道如何从应用程序扩展的视图控制器中启动父应用程序?
我只想从应用程序扩展中启动主应用程序。
在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
}
在WWDC 创建iOS和OS X扩展,第1部分 的演讲中,在大约22分钟的时间点,他们建议使用UIViewController的extensionContext中的openURL:completionHandler:
方法来打开自定义 URL scheme。
[self.extensionContext openURL:[NSURL URLWithString:@"your-app-custom-url-scheme://your-internal-url"]
completionHandler:nil];
我当前使用的应用程序中,通过操作扩展功能可以使其正常工作。
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()
}
}
我希望它能正常工作,并且可以在扩展应用程序和父应用程序之间共享数据。
AppDelegate
方法中的任何一个 func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey : Any] = [:]) -> Bool
或 func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool
都没有触发。 - Paul Bextension 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)
}
}
Use a UIWebView's loadRequest webView to load an NSURL request with your containing app's url. For example,
NSURL *url = [NSURL URLWithString:@"myurl"];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
[self.webView loadRequest:request];
Use a UIDocumentInteractionController and a custom file extension type to provide a link to your containing app (and your containing app only)
Start a "fake" NSURL session to get the following functionality: In iOS, if your extension isn’t running when a background task completes, the system launches your containing app in the background and calls the application:handleEventsForBackgroundURLSession:completionHandler: app delegate method.
我确定这段第二段是在Launcher被接受、拒绝,然后后来获得批准出售之后添加的。Apple允许任何Today小部件使用openURL:completionHandler:方法来打开小部件自己的包含应用程序。
如果您使用此方法从Today小部件打开其他应用程序,则您的App Store提交可能需要额外的审核以确保符合Today小部件的意图。
构建设置
。将仅需要应用程序扩展安全API
设置为NO
。UIApplication.shared.openURL(URL(string:"openPdf://")!)
来打开URL。请注意,您将收到'openURL' was deprecated in iOS 10.0 warning警告。因此,未来无法保证此方法能正常工作。
考虑使用本地通知来唤醒主机应用程序,而不是使用此方法。
APPLICATION_EXTENSION_API_ONLY
构建设置进行构建。 - jontelang这里是一个可行的解决方案(在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)
}
}
我在我的扩展中使用这段代码来打开主应用程序并使用自定义的 scheme 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)
}
openURL
放在那个ViewController里面,在viewDidAppear后调用了self.openURL(URL(string: "myapp://com.mydomain.share?urlparams")!)
。ViewController本身几乎是空的 - 我只是收集传入的文件并将它们保存到本地文件夹中,然后执行上述调用。不要忘记注册你的URL方案myapp
... - coyer