从我的应用程序中的 Today Extension(小部件)打开 Safari
Open Safari from my Today Extension (widget) within my app
我有一个带文本字段的 Today Extension。我想使用文本字段的内容作为 URL 在我的应用程序中打开浏览器。
这是我的 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")
}
})
}
您可以使用深度 linking 来做到这一点。
一旦您的应用响应自定义方案 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")
}
})
}
在您的应用中,就像前面描述的那样 link 您必须在您的应用委托中实现
func application(_ app: UIApplication, open url: URL,
options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool
在此方法中,url 将是您在应用程序扩展中创建的那个。这意味着它将是 my-app://openurl/{the url with percent escaping}
您将必须解析此 url,初始化包含 webView 的视图控制器并传递 url 以打开。
您可以使用@Giuseppe_Lanza 解决方案并解析您从 Today Extension Widget 收到的 url。但是,我将展示一个示例,其中您的 url 具有静态组件并根据用户在文本字段中的输入寻找诸如 https:/www.apple.com/homepod
或 https:/www.apple.com/iphone
的路径:
1- URL 方案: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)
}
Make sure to make add an identifier for this segue under the attributes
inspector as 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 或将 "?"
附加到您的 urlToLoad
就在你尝试附加 url.query 之前,就像我在 webView 控制器中所做的那样。
我有一个带文本字段的 Today Extension。我想使用文本字段的内容作为 URL 在我的应用程序中打开浏览器。
这是我的 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")
}
})
}
您可以使用深度 linking 来做到这一点。
一旦您的应用响应自定义方案 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")
}
})
}
在您的应用中,就像前面描述的那样 link 您必须在您的应用委托中实现
func application(_ app: UIApplication, open url: URL,
options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool
在此方法中,url 将是您在应用程序扩展中创建的那个。这意味着它将是 my-app://openurl/{the url with percent escaping}
您将必须解析此 url,初始化包含 webView 的视图控制器并传递 url 以打开。
您可以使用@Giuseppe_Lanza 解决方案并解析您从 Today Extension Widget 收到的 url。但是,我将展示一个示例,其中您的 url 具有静态组件并根据用户在文本字段中的输入寻找诸如 https:/www.apple.com/homepod
或 https:/www.apple.com/iphone
的路径:
1- URL 方案: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)
}
Make sure to make add an identifier for this segue under the attributes inspector as
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 或将 "?"
附加到您的 urlToLoad
就在你尝试附加 url.query 之前,就像我在 webView 控制器中所做的那样。