Ответ 1
Обновлено для Swift 3.0
Как было сказано, вы хотите зарегистрироваться на удаленные уведомления в applicationDidLaunchWithOptions:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
let pushSettings = UIUserNotificationSettings(types: [.alert, .badge, .sound], categories: nil)
UIApplication.shared.registerUserNotificationSettings(pushSettings)
UIApplication.shared.registerForRemoteNotifications()
}
Невозможно узнать, в каком режиме viewController вы будете, когда вернетесь с экрана lockScreen/Background. Что я делаю, я отправляю уведомление из приложения appDelegate. Когда вы получаете remoteNotification, вызывается didReceiveRemoteNotification в appDelegate.
func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
let notif = JSON(userInfo) // SwiftyJSON required
В зависимости от того, что содержит ваше уведомление, вы должны сначала убедиться, что он не нуль, а затем вызвать уведомление, которое будет улавливаться viewControllers, которое должно поймать это уведомление. Может выглядеть так: просто возьмите это как пример:
if notif["callback"]["type"] != nil{
NotificationCenter.default.post(name: Notification.Name(rawValue: "myNotif"), object: nil)
// This is where you read your JSON to know what kind of notification you received, for example :
}
Например, если вы получаете уведомление по сообщениям, и вы больше не вошли в систему, потому что токен истек, тогда уведомление никогда не будет уловлено в контроллере представления, потому что оно никогда не будет просмотрено.
Теперь для той части, где вы обнаружите уведомление в контроллере представления. В представленииWillAppear:
override func viewWillAppear(_ animated: Bool) {
NotificationCenter.default.addObserver(self, selector: #selector(self.catchIt), name: NSNotification.Name(rawValue: "myNotif"), object: nil)
}
Теперь, когда вы добавили этого наблюдателя, каждый раз, когда в этом контроллере вызывается уведомление, также будет вызываться функция catchIt. Вам нужно будет реализовать его в каждом контроллере представления, который вы хотите реализовать для конкретного действия.
func catchIt(_ userInfo: Notification){
if userInfo.userInfo?["userInfo"] != nil{
let prefs: UserDefaults = UserDefaults.standard
prefs.removeObject(forKey: "startUpNotif")
prefs.synchronize()
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc: RedirectAppInactiveVC = storyboard.instantiateViewController(withIdentifier: "RedirectAppInactiveVC") as! RedirectAppInactiveVC
self.navigationController?.pushViewController(vc, animated: true)
}
else{
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc: RedirectAppActiveVC = storyboard.instantiateViewController(withIdentifier: "RedirectAppActiveVC") as! RedirectAppActiveVC
self.navigationController?.pushViewController(vc, animated: true)
}
}
Не забывайте отменять подписку на уведомления при выходе из контроллера представления, иначе viewController, если он все еще находится в стеке, поймает уведомление и выполнит его (ну, возможно, вы захотите этого, но более безопасно знать, что вы вступают). Поэтому я предлагаю отказаться от подписки в viewWillDisappear:
override func viewWillDisappear(_ animated: Bool) {
NotificationCenter.default.removeObserver(self)
}
Выполняя это, вы загрузите требуемый viewController. Теперь мы все еще не рассматривали все случаи. Что делать, если вы еще не открыли приложение. Очевидно, что UIViewController не загружен, и никто из них не сможет поймать уведомление. Вы хотите знать, получили ли вы уведомление в файле didFinishLaunchingWithOptions: в appDelegate. Что я делаю:
let prefs: UserDefaults = UserDefaults.standard
if let remoteNotification = launchOptions?[UIApplicationLaunchOptionsKey.remoteNotification] as? NSDictionary {
prefs.set(remoteNotification as! [AnyHashable: Any], forKey: "startUpNotif")
prefs.synchronize()
}
Теперь вы указали, что приложение было запущено с помощью удаленного уведомления. В контроллерах, которые должны быть загружены сначала в вашем приложении, я предлагаю сделать следующее в viewDidAppear:
override func viewDidAppear(animated: Bool) {
let prefs:UserDefaults = UserDefaults.standard
if prefs.value(forKey: "startUpNotif") != nil{
let userInfo: [AnyHashable: Any] = ["inactive": "inactive"]
NotificationCenter.default.post(name: Notification.Name(rawValue: "myNotif"), object: nil, userInfo: userInfo as [AnyHashable: Any])
}
Надеюсь, это поможет. Я также создал репозиторий github, чтобы проиллюстрировать его локальными уведомлениями: Local Observation Pattern (аналогично удаленным уведомлениям). Аналогичную логику можно реализовать с помощью корневого представления Controller Локальный шаблон уведомлений Local, я лично думаю, что это будет зависеть от того, что вы хотите реализовать.