在我的应用程序中从我的今日扩展(小部件)打开Safari

我有一个带有文本字段的今日扩展。 我想使用文本字段的内容作为URL在我的应用程序中打开浏览器。

这是我的widget的TodayViewController.swift

import UIKit import SafariServices import NotificationCenter // This extension to remove the white spaces from what pasteed extension String { func replace(string:String, replacement:String) -> String { return self.replacingOccurrences(of: string, with: replacement, options: NSString.CompareOptions.literal, range: nil) } func removeWhitespace() -> String { return self.replace(string: " ", replacement: "") } } class TodayViewController: UIViewController, NCWidgetProviding { var clearNumber: String? override func viewDidLoad() { super.viewDidLoad() } func widgetPerformUpdate(completionHandler: (@escaping (NCUpdateResult) -> Void)) { // Perform any setup necessary in order to update the view. // If an error is encountered, use NCUpdateResult.Failed // If there's no update required, use NCUpdateResult.NoData // If there's an update, use NCUpdateResult.NewData completionHandler(NCUpdateResult.newData) } @IBOutlet weak var textBox: UITextField! @IBAction func clearNumber(_ sender: Any) { if textBox.hasText == true { textBox.text = "" }else{ return } } @IBAction func pasteNumber(_ sender: Any) { if let myString = UIPasteboard.general.string { let pasteNumber = myString.removeWhitespace() textBox.insertText(pasteNumber) }else{ return } } @IBAction func goButton(_ sender: Any) { let myAppUrl = URL(string: "main-screen:")! extensionContext?.open(myAppUrl, completionHandler: { (success) in if (!success) { print("error: failed to open app from Today Extension") } }) } 

您可以使用@Giuseppe_Lanza解决方案并解析从Today Extension Widget收到的URL。 但是,我会展示一个示例,其中您的url包含静态组件,并根据用户在textField中的输入查找https:/www.apple.com/homepodhttps:/www.apple.com/iphone等路径:

1- URL Scheme: myAppName

2-添加此项以使用小部件打开您的应用

 @IBAction func goButton(_ sender: Any) { openApp(widgetText: "\(textBox.text!)") } func openApp(widgetText:String) { let str = "myAppName://https://www.apple.com/\(widgetText)" let url = URL(string: str)! if textBox.hasText == true { extensionContext?.open(url, completionHandler: { (success) in if (!success) { print("error: 🧐") } }) } } 

3- AppDelegate

定义一个变量并将收到的url传递给webViewController,将在那里解析url。

 open var receivedUrl:URL? func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool{ receivedUrl = url //You need to alter this navigation to match your app requirement so that you get a reference to your previous view.. window?.rootViewController?.performSegue(withIdentifier: "toDeepLink", sender: nil) } 

确保在属性检查器下为此segue添加标识符toDeepLink

4- WebView和解析url现在你可以像这样获得receivedUrl

  override func viewDidLoad() { super.viewDidLoad() let myAppDelegate = UIApplication.shared.delegate as! AppDelegate print("receivedUrl \(myAppDelegate.receivedUrl!)") //url Parsing & getting rid off urlScheme let urlToLoad = URL(string: "\(myAppDelegate.receivedUrl!.host! + ":" + myAppDelegate.receivedUrl!.path)")! print(urlToLoad) let urlRequest = URLRequest(url: urlToLoad) webView.load(urlRequest) } 

否则,您需要以正确的方式解析它,如字典,以将动态值分配到字典中的相应键,从而分配给您的URL或附加"?" 就像我在webView控制器中那样尝试追加url.query之前到你的urlToLoad

您可以使用深层链接来完成此操作。

首先定义自定义URL方案

一旦您的应用响应自定义方案my-app://您就可以从todayViewController打开您的应用。

 @IBAction func goButton(_ sender: Any) { let myAppUrl = URL(string: "my-app://openurl/\(yourURL.addingPercentEncoding(withAllowedCharacters: .urlPathAllowed))")! extensionContext?.open(myAppUrl, completionHandler: { (success) in if (!success) { print("error: failed to open app from Today Extension") } }) } 

在您的应用中,就像您在上一个链接中所描述的那样,您必须在您的应用委托中实施

 func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool 

在此方法中,url将是您在应用扩展程序中创建的url。 这意味着它将是my-app://openurl/{the url with percent escaping}你必须解析这个url,初始化包含webView的视图控制器并传递要打开的url。