How to open Specific View controller on Widgets/ Today Extension click
According to your requirement, I have created a sample to get this working correctly.
1. First of all in TodayViewController
interface, create 3 different UIButtons
and give their tag
values to uniquely identify them.
Here I have given tags as: 1, 2, 3
to First, Second and Third
UIButton
.
2. Next you need to write the code to open your Containing App from Today Extension. In TodayViewController
create an @IBAction
for and connect it to all three UIButtons
.
@IBAction func openAppController(_ sender: UIButton)
{
if let url = URL(string: "open://\(sender.tag)")
{
self.extensionContext?.open(url, completionHandler: nil)
}
}
In the above code, tag will be added to the url scheme to identify which UIViewController
needs to be opened on UIButton
press. So the url will look something like: open://1
3. In the Containing App's URL Types
need to make an entry for URL Scheme
, i.e
As evident from the above screenshot, there is no need to make entry for each url that you want to open from your extensions. URLs
having same url scheme
have only a single entry.
4. When the containing app is opened from extension, you can get the handle in AppDelegate’s
application(_ : url: sourceApplication: annotation: )
method. Here, you can handle which controller to open i.e.
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool
{
if url.scheme == "open"
{
switch url.host
{
case "1":
//Open First View Controller
case "2":
//Open Second View Controller
case "3":
//Open Third View Controller
default:
break
}
}
return true
}
url.scheme
identifies the scheme of URL
i.e. open
and url.host
identifies the host component in the URL
which is currently set to the UIButton's tag value
which you can use to uniquely identify which UIButton
is pressed and what to de next accordingly.
For more on Today Extensions, you can refer to: https://hackernoon.com/app-extensions-and-today-extensions-widget-in-ios-10-e2d9fd9957a8
Let me know if you still face any issues regarding this.
add a new scheme for your App
enter image description here
as Shown above image...
then, write a code below on IBAction of your Today Extension
@IBAction func btnFirstWidgetAction() {
let url: URL? = URL(string: "schemename://secondViewController")!
if let appurl = url { self.extensionContext!.open(appurl, completionHandler: nil) }
}
@IBAction func btnSecondWidgetAction() {
let url: URL? = URL(string: "schemename://secondViewController")!
if let appurl = url { self.extensionContext!.open(appurl, completionHandler: nil) }
}
@IBAction func btnThirdWidgetAction() {
let url: URL? = URL(string: "schemename://thirdViewController")!
if let appurl = url { self.extensionContext!.open(appurl, completionHandler: nil) }
}
than, add method application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) in AppDelegate file and write code to redirect in specific ViewController in this method.
//call when tap on Extension and get url that is set into a ToadyExtension swift file...
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
let urlPath : String = url.absoluteString
print(urlPath)
if self.isContainString(urlPath, subString: "firstViewController") {
//here go to firstViewController view controller
}
else if self.isContainString(urlPath, subString: "firstViewController") {
//here go to secondViewController view controller
}
else {
//here go to thirdViewController view controller
}
return true
}
this method used for check your string is contains as sub string that are given in widget button action. if contain than true otherwise false
func isContainString(_ string: String, subString: String) -> Bool {
if (string as NSString).range(of: subString).location != NSNotFound { return true }
else { return false }
}