Tarvo Mäesepp Tarvo Mäesepp - 5 months ago 36
Swift Question

How to call or trigger notification function in AppDelegate from ViewController or somewhere else?

How could I call this kind of method which is inside

ViewController
, inside
appDelegate
or somewhere else:

func contactDelete(notification : NSNotification){}


And I gotta call it inside
appDelegate
inside

`didFinishLaunchingWithOptions` here or inside other classes:



func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.

let tintColor = UIColor(red: 252/255, green: 72/255, blue: 49/255, alpha: 1)
window!.tintColor = tintColor

if let aLaunchOptions = launchOptions { // Checking if there are any launch options.
// Check if there are any local notification objects.
if let notification = (aLaunchOptions as NSDictionary).objectForKey("UIApplicationLaunchOptionsLocalNotificationKey") as? UILocalNotification {
// Handle the notification action on opening. Like updating a table or showing an alert.
UIAlertView(title: notification.alertTitle, message: notification.alertBody, delegate: nil, cancelButtonTitle: "OK").show()
let root : UIViewController = self.window!.rootViewController! as UIViewController
let alertview = JSSAlertView().show(root, title: "Oops!", text: "Unable to add the new Contact, check contact permission from Settings.", buttonText: "Check it", cancelButtonText: "Nope", color: UIColor.init(red: 0.216, green:0.043, blue:0.129, alpha: 1))
alertview.addAction(contactDelete)
alertview.setTextTheme(.Light)


}
}


It needs some kind of extra argument but I do not know what argument. I even can't call it inside
viewDidLoad
method. I tried to trigger it like this but it won't work:

NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(ViewController.contactDelete(_:)), name:DELETECONTACT, object: nil)

Answer

In your Appdelegate code you are assigning RootviewController based on Notification arrived or simple launch using:

if let notification = (aLaunchOptions as NSDictionary).objectForKey("UIApplicationLaunchOptionsLocalNotificationKey") as? UILocalNotification {

But you are setting NotificationViewController as a rootViewController and you are addObserver on MainViewController so when you get notification and your rootView set as NotificationViewController you there is wont NSNotificationCenter created and you wont able to post it. so i suggest to create code like following:

Your appdelegate didFinishLaunchingWithOptions method:

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        // Override point for customization after application launch.
        self.window = UIWindow(frame: UIScreen.mainScreen().bounds)
        let tintColor = UIColor(red: 252/255, green: 72/255, blue: 49/255, alpha: 1)
        window!.tintColor = tintColor

        application.registerForRemoteNotifications()
        application.registerUserNotificationSettings(UIUserNotificationSettings(forTypes: .Alert , categories: nil))


        let mainStoryboardIpad : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
        let initialViewControlleripad : UIViewController = mainStoryboardIpad.instantiateViewControllerWithIdentifier("first") as UIViewController


        let navController: UINavigationController = UINavigationController(rootViewController: initialViewControlleripad)
        navController.navigationBarHidden = true

        self.window?.rootViewController = navController
        self.window?.makeKeyAndVisible()


        let notification = launchOptions?[UIApplicationLaunchOptionsLocalNotificationKey] as! UILocalNotification!
        if (notification != nil) {


            runAfterDelay(2.0) {  // add 2 second delay of call method open notificationViewController from mainViewController
                self.FireNewViewControlelr(notification.userInfo!)
            }

        }
        return true
    }

Following is two method for calling NotificationViewController:

func FireNewViewControlelr(Value: [NSObject : AnyObject]) {

    print("userInf \(Value)")

    let navigationController: UINavigationController = (self.window!.rootViewController as! UINavigationController)
    let mainStoryboardIpad : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    let initialViewControlleripad : UIViewController = mainStoryboardIpad.instantiateViewControllerWithIdentifier("Main") as! NotificationViewController
    NSNotificationCenter.defaultCenter().postNotificationName(DELETECONTACT, object: Value)
    navigationController.pushViewController(initialViewControlleripad, animated: true)

}


func runAfterDelay(delay: NSTimeInterval, block: dispatch_block_t) {
    let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay * Double(NSEC_PER_SEC)))
    dispatch_after(time, dispatch_get_main_queue(), block)
}

If your app in background mode and you open app from notification banner tapped didReceiveLocalNotification look like following:

func application(application: UIApplication, didReceiveLocalNotification notification: UILocalNotification) {

        print("notification - tapped")

        if application.applicationState == UIApplicationState.Active {
            print("App already open")

        } else {
            print("App opened from Notification")


            runAfterDelay(2.0) {
                self.FireNewViewControlelr(notification.userInfo!)
            }

        }

    }

Change code in following method:

 func FireNewViewControlelr(Value: [NSObject : AnyObject]) {

        print("userInf \(Value)")

        let navigationController: UINavigationController = (self.window!.rootViewController as! UINavigationController)
        let mainStoryboardIpad : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
        let initialViewControlleripad : NotificationViewController = mainStoryboardIpad.instantiateViewControllerWithIdentifier("Main") as! NotificationViewController
        initialViewControlleripad.notificationInfo = Value
        navigationController.pushViewController(initialViewControlleripad, animated: true)

    }

in NotificationViewController

  var notificationInfo = [NSObject : AnyObject]()

    override func viewDidLoad() {
        super.viewDidLoad()


        print("data is \(notificationInfo)")


        // Do any additional setup after loading the view.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    @IBAction func action(sender: AnyObject) {

         NSNotificationCenter.defaultCenter().postNotificationName(DELETECONTACT, object: notificationInfo)
       self.navigationController?.popToRootViewControllerAnimated(true)
    }