How to Open a Specific View Controller On didReceiveRemoteNotification when application is in back ground
1.Firstly you should Turn On Background Fetch in app "Capabilities"
2. Then use following code in app delegate
In AppDelegate class add following code:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
// print(userInfo)
let vc = mainStoryBoard.instantiateViewController(withIdentifier: "destinationVC") as! destinationVC
self.visibleNavController.pushViewController(vc, animated: true)
}
For iOS 10 use following code:
1.Import
import UserNotifications
For foreground fetch
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, willPresent notification: UNNotification, withCompletionHandler completionHandler: @escaping (_ options: UNNotificationPresentationOptions) -> Void) {
var userInfo = NSDictionary()
userInfo = notification.request.content.userInfo as NSDictionary
let pay = userInfo as NSDictionary
let driverLocationVC = mainStoryBoard.instantiateViewController(withIdentifier: "destinationVC") as! destinationVC
self.visibleNavController.pushViewController(driverLocationVC, animated: true)
}
For the background
@available(iOS 10.0, *)
func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
print("Userinfo \(response.notification.request.content.userInfo)")
var userInfo = NSDictionary()
userInfo = response.notification.request.content.userInfo as NSDictionary
print(userInfo)
let driverLocationVC = mainStoryBoard.instantiateViewController(withIdentifier: "DriverLocationVC") as! DriverLocationVC
self.visibleNavController.pushViewController(driverLocationVC, animated: true)
}
For device token fetch
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
let tokenString = deviceToken.reduce("", {$0 + String(format: "%02X", $1)})
print("Got token data! \(tokenString)")
UserDefaults.standard.set(tokenString, forKey: "device_token")
UserDefaults.standard.synchronize()
}
Present specific view controller in didReceiveRemoteNotification with Swift
Try this
let storyboard = UIStoryboard(name: "YourStoryboardName", bundle: nil)
let rootVC = storyboard.instantiateViewControllerWithIdentifier("HomeVC") as! UITabBarController
if PFUser.currentUser() != nil {
rootVC.selectedIndex = 2 // Index of the tab bar item you want to present, as shown in question it seems is item 2
self.window!.rootViewController = rootVC
}
Swift - How to open specific view controller when push notification received?
When you app is in closed state you should check for launch option in
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { }
and call your API.
Example:
if let option = launchOptions {
let info = option[UIApplicationLaunchOptionsKey.remoteNotification]
if (info != nil) {
goAnotherVC()
}
}
How to push a view controller from App Delegate on didReceiveRemoteNotification in Swift?
I managed to get it working as I needed with help from both Sh_Khan and the answer I found in this thread: How can I show ViewController in UITabBarController?
My initial view controller is a tabBar and therefore, this is the correct code for me:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
let info = userInfo as NSDictionary
let name: String = info.value(forKey: "view-controller") as! String
switch name {
case "controller1":
let storyboard = UIStoryboard.init(name: "Main", bundle: nil)
let controller1VC = storyboard.instantiateViewController(withIdentifier: "controller1VC") as! Controller1VC
let tabBar = self.window?.rootViewController as? UITabBarController
let nav = tabBar?.selectedViewController as? UINavigationController
nav?.pushViewController(controller1VC, animated: true)
default:
print("Nothing")
}
}
So this code will essentially convert the tabBar
to a UINavigationController
allowing for a pushViewController
to work.
I hope this helps anyone else.
Handle remote notification from within view controller
In your app delegate, do:
weak var configureiMacViewController: ConfigureiMacViewController?
Create helper functions to keep your code clean and readable:
private func updateiMacImage(_ image: UIImage, in existingViewController: ConfigureiMacViewController) {
existingViewController.image = image
}
private func showiMacImage(_ image: UIImage) {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let rootTabBarController = self.window?.rootViewController as! UITabBarController
let firstNavigationController = storyboard.instantiateViewController(withIdentifier: "initialVC1") as! UINavigationController
rootTabBarController.viewControllers![0] = firstNavigationController
//the viewController to present
let viewController = storyboard.instantiateViewController(withIdentifier: "configureiMac") as! ConfigureiMacViewController
configureiMacViewController = viewController
// present VC
firstNavigationController.pushViewController(viewController, animated: true, completion: {
viewController.image = UIImage(named: "iMac" + iMacConfig)
})
}
Then update:
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
if let data = userInfo["showiMac"] as? [String: String], let iMacConfig = data["iMacConfig"] {
let image = UIImage(named: "iMac" + iMacConfig)
if let existingViewController = configureiMacViewController {
updateiMacImage(image, in: existingViewController)
} else {
showiMacImage(image)
}
completionHandler(.noData)
}
}
The weak var in your AppDelegate will store a reference to your view controller but the "weak" keyword will allow the view controller to be released from memory if it is dismissed, in which case the variable will be nil the next time you try to access it. If the view controller is still visible, then its value will still be defined and you will be able to re-use it to update the image.
You will most likely have to also update your ConfigureiMacViewController code to:
var image: UIImage! {
didSet {
imageView.image = image
}
}
override func viewDidLoad() {
super.viewDidLoad()
imageView.image = image
}
This ensure that if the view controller was already loaded and displayed, but you update the image variable, that the image view is loaded with the most recent image.
Good luck!
Load a specific viewController on push notification Swift 2 AppDelegate
I want to respond to my own question because I think maybe someone is facing the same situation, I have to say thanks to @Muneeba
Well, first of all you have to know if your remote push notification needs to do a background fetch, this is important because if so the didReceiveRemoteNotification
is called twice (first when you click on the notification alert, seconds when it opens the app), so you have to be aware of this.
In my case I didn't do a background fetch, so my content-available:false
flag was set to false.
Next thing to do is add you desire ["key":value]
to the notification payload to know whether you want to open a specific view controller or not.
Manage whether open a view controller or not.
In my app I want to open a alert control pop up always showing the body of the push notification (with a OK button) and only when certain value is set open a alert control with a question to the user whether or not he wants to open the new content that arrives (normally this content is a web based content that open a webview embedded in a view controller)
In the didReceiveRemoteNotification
:
if let mensaje = userInfo["m"] as? String {
// Here is where I know if the value is set in the notification payload
let alertCtrl = UIAlertController(title: titulo, message: mensaje as String, preferredStyle: UIAlertControllerStyle.Alert)
if url == nil {
alertCtrl.addAction(UIAlertAction(title: "OK", style: .Destructive, handler: nil))
} else {
alertCtrl.addAction(UIAlertAction(title: "Ver receta", style: .Default, handler: {
action in
let storyboard = UIStoryboard(name: "Main", bundle: nil)
//self.window?.rootViewController = storyboard.instantiateViewControllerWithIdentifier("TabbedController") as! UITabBarController
let navigationController = storyboard.instantiateViewControllerWithIdentifier("pushNotificationNavigation") as! UINavigationController
let dVC:NotTestViewController = navigationController.topViewController as! NotTestViewController
// This is for passing the URL to the view Controller
dVC.url = self.url!
self.window?.rootViewController?.presentViewController(navigationController, animated: true, completion: {})
})
)
alertCtrl.addAction(UIAlertAction(title: "Cancelar", style: .Destructive, handler: nil))
}
// Find the presented VC...
var presentedVC = self.window?.rootViewController
while (presentedVC!.presentedViewController != nil) {
presentedVC = presentedVC!.presentedViewController
}
presentedVC!.presentViewController(alertCtrl, animated: true, completion: nil)
handler(UIBackgroundFetchResult.NoData)
}
didReceiveRemoteNotification presentViewController from anywhere when running
Fixed it by changing:
rootViewController.presentViewController(navigationController, animated: true, completion: nil)
to:
rootViewController.visibleViewController!.presentViewController(navigationController, animated: false, completion: nil)
How to get specific view controller on click of local Notification?..I tried all possible way to achieve but couldn't
In AppDelegate
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void (^)(void))completionHandler {
UINavigationController *nvc = (UINavigationController *)self.window.rootViewController;
// Currently visible ViewController
UIViewController *vc = nvc.visibleViewController;
UIStoryboard *sb = [UIStoryboard storyboardWithName:@"Main"
bundle:NULL];
// YourViewController to Push in Your case SecondViewController
yourViewController *myVc= [sb instantiateViewControllerWithIdentifier:@"yourViewController"];
[navigationController pushViewController:myVc animated:true];
}
You can check Particular notification by response.actionIdentifier
in Your case with response.notification.request.content.categoryIdentifier
You check particular Notification
To set catagoryIdentifier
muContent.categoryIdentifier = @"Your_Identifier";
Opening specific view with navigation controller from push notication
What you're doing is completely replacing the root view controller of your application, this means that all the current UI will be discarded.
What you should do instead is to use your knowledge of your application to direct it to the new content. For example, if your root view controller is a navigation controller, you can cast rootViewController
to a nav controller and push it (this will fail if your root view controller is something else, like a tab bar controller).
guard let vc = storyboard.instantiateViewController(withIdentifier: "notification") as? NotificationViewController else {
fatalError("Main Storyboard doesn't have a notification controller")
}
guard let nav = self.window?.rootViewController as? UINavigationController else {
return //handle unexpected state
}
nav.push(vc, animated: true)
Another option would be to embed your notification controller into a navigation controller, add a Close
button, and present it modally, that way you can present it on top of rootViewController
no matter what that controller is.
Related Topics
How to Send Msmessage in Messages Extension
Manage a Uipickerview from an External Class - Using Swift
@Ibdesignable - View Not Rendering as Expected
How Is It I Can Animate the Change in Bar Tint Color of a Uinavigationbar But Not a Uitabbar
How to Set Cmutablepointer<Objcbool> to False in Swift
Swift Add Line Above to Control
Save Image with the Correct Orientation - Swift & Core Image
How to Convert This Opengl Pointer Math to Swift
How to Create a Rounded Rectangle Label in Xcode 7 and Swift 2
Geolocation by Iphone's Ip Address
Auto-Sizing Uicollectionview Headers
Swift - Uipopovercontroller in iOS 8
How to Share Published Model Between Two View Models in Swiftui
Hidden Property Cannot Be Changed Within an Animation Block
How to Insert Items at 0 Index to the Realm Container