Невозможно опубликовать уведомление от AppDelegate при обработке действия localNotification

В моем делегате приложения я пытаюсь настроить LocalNotification ActionHandler для выполнения перехода и отправки уведомления целевому ViewController для запуска функции в этом классе, но где-то вдоль линии уведомление не публикуется или не принимается должным образом.

Стоит отметить, что на данный момент целевой контроллер представления не инициализирован.

Вот мой код на данный момент: Фрагмент из AppDelegate:

func application(application: UIApplication, handleActionWithIdentifier identifier: String?, forLocalNotification notification: UILocalNotification, completionHandler: () -> Void) {


    if identifier == "mainAction" {

        self.window?.makeKeyAndVisible()
        self.window?.rootViewController?.navigationController?.popToRootViewControllerAnimated(true)
        (self.window?.rootViewController as? UINavigationController)?.viewControllers.first?.performSegueWithIdentifier("Segue", sender: self)
        NSNotificationCenter.defaultCenter().postNotificationName("NC_SegueDidPerform", object: nil)    
}

а вот в принимающем View Controller:

override func viewDidLoad() {
    super.viewDidLoad()


    NSNotificationCenter.defaultCenter().addObserverForName("NC_SegueDidPerform", object: nil, queue: nil, usingBlock: ({ (notification: NSNotification!)  in

        print ("working")
    }))
}

Я также пытался поместить наблюдателя в ViewWillApear и ViewDidAppear, но безрезультатно. Блок просто не выполняется!

Как мне заставить его работать, чтобы я мог получать уведомление (или любой вид «сигнала» в целевом контроллере представления?

Заранее спасибо.


person Glenncito    schedule 25.09.2015    source источник
comment
Вы ответили на свой вопрос.   -  person user523234    schedule 26.09.2015
comment
Я уточнил свой вопрос. Как мне получить уведомление в целевом контроллере представления?   -  person Glenncito    schedule 26.09.2015
comment
performSegue не является немедленным, поэтому вы отправляете уведомление до его завершения. Поскольку вы выталкиваете все контроллеры перед переходом, у вас нет контроллеров-наблюдателей, если я что-то не упустил? Единственными контроллерами являются корень навигационного контроллера и конечный контроллер перехода. Было бы лучше просто сообщить целевому контроллеру, что он был отправлен в результате действия с помощью метода prepareForSegue корневого контроллера.   -  person Rory McKinnel    schedule 26.09.2015
comment
В этом случае вам не нужно публиковать уведомление. Просто вызовите целевой VC и прямо скажите ему, что вы хотите, чтобы он сделал для этого локального уведомления, которое вы только что получили.   -  person user523234    schedule 26.09.2015
comment
Я хочу иметь возможность отправлять данные через userInfo, поэтому я надеялся, что бит уведомления будет работать, поскольку контроллер представления назначения зависит от данных. Итак, вы говорите, что я должен вызвать метод «prepareForSegue», чтобы получить доступ к переменным целевого VC?   -  person Glenncito    schedule 26.09.2015
comment
Добавьте в корневой контроллер метод handleMainAction, который принимает userInfo в качестве аргумента. В этом методе вызовите performSegue, и вы можете передать userInfo в prepareForSegue целевому контроллеру. Я не вижу необходимости в уведомлениях, когда ты знаешь, кто единственный и неповторимый наблюдатель. Так что ИМХО, просто используйте методы, описанные в начале комментария.   -  person Rory McKinnel    schedule 26.09.2015


Ответы (1)


Вы делаете это неправильно. Как вы правильно заметили, вызов performSegueWithIdentifier: не гарантирует немедленную доступность контроллера представления, поэтому ваше уведомление о том, что вы запускаете следующую строку, не достигает целевого контроллера представления. Предлагаемый Apple способ заключается в реализации prepareForSegue: и передаче данных в конечный VC. Этот метод позволяет вызываемому абоненту передать любые нужные данные в конечный виртуальный канал.

override func prepareForSegue(segue: UIStoryboardSegue!, sender: AnyObject!) {
   if (segue.identifier == "Segue") {
    // pass data to next view
   }
}
person Abhinav    schedule 26.09.2015
comment
Я пробовал это, но это не сработает, если я поставлю его в AppDelegate, похоже. Следует ли это вызывать из rootViewController? - person Glenncito; 26.09.2015
comment
Реализуйте это в исходном VC, откуда начинается переход. Если это вообще новый VC, вам нужно будет инициализировать его из раскадровки и передать данные непосредственно созданному объекту. - person Abhinav; 26.09.2015