Определить, было ли приложение запущено/открыто из push-уведомления

Можно ли узнать, было ли приложение запущено/открыто из push-уведомления?

Я думаю, что запускающее событие можно поймать здесь:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    if (launchOptions != nil) {
         // Launched from push notification
         NSDictionary *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];

    }
}

Однако, как я могу обнаружить, что он был открыт из push-уведомления, когда приложение было в фоновом режиме?

Ответ 1

Смотрите этот код:

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
    if ( application.applicationState == UIApplicationStateInactive || application.applicationState == UIApplicationStateBackground  )
    {
         //opened from a push notification when the app was on background
    }
}

то же, что и

-(void)application:(UIApplication *)application didReceiveLocalNotification (UILocalNotification *)notification

Ответ 2

поздно, но может быть полезно

Когда приложение не запущено

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

называется..

где нужно проверить push-уведомление

NSDictionary *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (notification) {
    NSLog(@"app recieved notification from remote%@",notification);
    [self application:application didReceiveRemoteNotification:notification];
} else {
    NSLog(@"app did not recieve notification");
}

Ответ 3

Проблема заключалась в правильном обновлении представления после запуска приложения. Здесь сложны последовательности жизненных циклов, которые запутываются.

Методы жизненного цикла

Наше тестирование для iOS 10 выявило следующие последовательности жизненных циклов для различных случаев:

DELEGATE METHODS CALLED WHEN OPENING APP  

Opening app when system killed or user killed  
    didFinishLaunchingWithOptions  
    applicationDidBecomeActive    

Opening app when backgrounded  
    applicationWillEnterForeground  
    applicationDidBecomeActive  

DELEGATE METHODS WHEN OPENING PUSH

Opening push when system killed
    [receiving push causes didFinishLaunchingWithOptions (with options) and didReceiveRemoteNotification:background]
    applicationWillEnterForeground
    didReceiveRemoteNotification:inactive
    applicationDidBecomeActive

Opening push when user killed
    didFinishLaunchingWithOptions (with options)
    didReceiveRemoteNotification:inactive [only completionHandler version]
    applicationDidBecomeActive

Opening push when backgrounded
    [receiving push causes didReceiveRemoteNotification:background]
    applicationWillEnterForeground
    didReceiveRemoteNotification:inactive
    applicationDidBecomeActive

Проблема

Итак, теперь нам нужно:

  • Определите, открывается ли приложение при нажатии кнопки
  • Обновить представление в зависимости от состояния нажатия
  • Очистите состояние, чтобы последующие открытия не возвращали пользователя в ту же позицию.

Сложный бит заключается в том, что обновление представления должно происходить, когда приложение фактически становится активным, что во всех случаях является одним и тем же методом жизненного цикла.

Эскиз нашего решения

Вот основные компоненты нашего решения:

  • Сохраните переменную экземпляра notificationUserInfo в AppDelegate.
  • Установите notificationUserInfo = nil как в applicationWillEnterForeground, так и в didFinishLaunchingWithOptions.
  • Установите notificationUserInfo = userInfo в didReceiveRemoteNotification:inactive
  • От applicationDidBecomeActive всегда вызывается пользовательский метод openViewFromNotification и проходит self.notificationUserInfo. Если self.notificationUserInfo равно nil, тогда возвращайтесь раньше, иначе открывайте представление, основанное на состоянии уведомления, найденном в self.notificationUserInfo.

Объяснение

При открытии с push didFinishLaunchingWithOptions или applicationWillEnterForeground всегда вызывается непосредственно перед didReceiveRemoteNotification:inactive, поэтому мы сначала reset notificationUserInfo в этих методах, чтобы не было состояния устаревших. Затем, если вызывается didReceiveRemoteNotification:inactive, мы знаем, что мы открываем от нажатия, поэтому мы устанавливаем self.notificationUserInfo, который затем выбирается applicationDidBecomeActive, чтобы перенаправить пользователя в правильное представление.

Существует один последний случай, когда пользователь открывает приложение в коммутаторе приложений (т.е. дважды нажав кнопку "домой", когда приложение находится на переднем плане), а затем получает push-уведомление. В этом случае вызывается только didReceiveRemoteNotification:inactive, и ни WillEnterForeground, ни didFinishLaunching не вызываются, поэтому вам нужно какое-то особое состояние для обработки этого случая.

Надеюсь, что это поможет.

Ответ 4

Это хорошо изношенное сообщение... но до сих пор не хватает фактического решения (как указано в различных комментариях).

Исходный вопрос заключается в обнаружении, когда приложение было запущено/ открыт из push-уведомления, например. пользователь нажимает на уведомление. Ни один из ответов на самом деле не охватывает этот случай.

Причина может быть видна в потоке вызовов, когда приходит уведомление, application:didReceiveRemoteNotification...

вызывается, когда уведомление получает И снова, когда уведомление используется пользователем. Из-за этого вы не можете сказать, просто взглянув на UIApplicationState, чтобы пользователь нажал на него.

Кроме того, вам больше не нужно обрабатывать ситуацию "холодного запуска" приложения в application:didFinishLaunchingWithOptions..., поскольку application:didReceiveRemoteNotification... вызывается снова после запуска в iOS 9+ (возможно, 8).

Итак, как вы можете определить, нажал ли пользователь нажатие на цепочку событий? Мое решение - отметить время, когда приложение начинает выходить из фонового или холодного старта, а затем проверять это время в application:didReceiveRemoteNotification.... Если оно меньше 0,1 с, то вы можете быть уверены, что нажатие запускает запуск.

Swift 2.x

class AppDelegate: UIResponder, UIApplicationDelegate {

  var wakeTime : NSDate = NSDate()        // when did our application wake up most recently?

  func applicationWillEnterForeground(application: UIApplication) {    
    // time stamp the entering of foreground so we can tell how we got here
    wakeTime = NSDate()
  }

  func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
    // ensure the userInfo dictionary has the data you expect
    if let type = userInfo["type"] as? String where type == "status" {
      // IF the wakeTime is less than 1/10 of a second, then we got here by tapping a notification
      if application.applicationState != UIApplicationState.Background && NSDate().timeIntervalSinceDate(wakeTime) < 0.1 {
        // User Tap on notification Started the App
      }
      else {
        // DO stuff here if you ONLY want it to happen when the push arrives
      }
      completionHandler(.NewData)
    }
    else {
      completionHandler(.NoData)
    }
  }
}

Swift 3

class AppDelegate: UIResponder, UIApplicationDelegate {

    var wakeTime : Date = Date()        // when did our application wake up most recently?

    func applicationWillEnterForeground(_ application: UIApplication) {
      // time stamp the entering of foreground so we can tell how we got here
      wakeTime = Date()
    }

  func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {

      // ensure the userInfo dictionary has the data you expect
      if let type = userInfo["type"] as? String, type == "status" {
        // IF the wakeTime is less than 1/10 of a second, then we got here by tapping a notification
        if application.applicationState != UIApplicationState.background && Date().timeIntervalSince(wakeTime) < 0.1 {
          // User Tap on notification Started the App
        }
        else {
          // DO stuff here if you ONLY want it to happen when the push arrives
        }
        completionHandler(.newData)
      }
      else {
        completionHandler(.noData)
      }
    }
}

Я тестировал это для обоих случаев (приложение в фоновом режиме, приложение не работает) на iOS 9+, и оно работает как шарм. 0.1s также довольно консервативен, фактическое значение составляет ~ 0.002s, так что 0,01 тоже хорошо.

Ответ 5

Swift 2.0 Для состояния "Не работает" (локальное и удаленное уведомление)

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {


// Handle notification
if (launchOptions != nil) {

    // For local Notification
    if let localNotificationInfo = launchOptions?[UIApplicationLaunchOptionsLocalNotificationKey] as? UILocalNotification {

        if let something = localNotificationInfo.userInfo!["yourKey"] as? String {
            self.window!.rootViewController = UINavigationController(rootViewController: YourController(yourMember: something))
        }


    } else

    // For remote Notification
    if let remoteNotification = launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey] as! [NSObject : AnyObject]? {

        if let something = remoteNotification["yourKey"] as? String {
            self.window!.rootViewController = UINavigationController(rootViewController: YourController(yourMember: something))
        }
    }

}


return true

}

Ответ 6

В application:didReceiveRemoteNotification: проверьте, получили ли вы уведомление, когда ваше приложение находится на переднем плане или в фоновом режиме.

Если он был получен в фоновом режиме, запустите приложение из уведомления.

-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
    if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive) {
        NSLog(@"Notification received by running app");
    } else {
        NSLog(@"App opened from Notification");
    }
}

Ответ 7

Когда приложение завершается, а пользователь нажимает на push-уведомление

public func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
   if launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey] != nil {
      print("from push")
    }
}

Когда приложение находится в фоновом режиме, а пользовательские нажатия на кнопку push notificaion

Если пользователь открывает ваше приложение из системного предупреждения, система может снова вызвать этот метод , когда ваше приложение собирается ввести передний план, чтобы вы могли обновить свой пользовательский интерфейс и отобразить информацию относящихся к уведомлению.

public func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
  if application.applicationState == .Inactive {
    print("from push")
  }
}

В зависимости от вашего приложения он также может отправить вам тихий push с content-available внутри aps, поэтому имейте это в виду:) См. fooobar.com/questions/47042/...

Ответ 8

Для быстрого:

func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
    PFPush.handlePush(userInfo)

    if application.applicationState == UIApplicationState.Inactive || application.applicationState == UIApplicationState.Background {
        //opened from a push notification when the app was on background

    }

}

Ответ 9

Да, этот метод можно обнаружить в appDelegate:

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
      /* your Code*/
}

Для локального уведомления:

- (void)application:(UIApplication *)application
didReceiveLocalNotification:(UILocalNotification *)notification
{
         /* your Code*/
}

Ответ 10

Размещать это для пользователей Xamarin.

Ключом к определению того, было ли приложение запущено с помощью push-уведомления, является метод AppDelegate.FinishedLaunching(UIApplication app, NSDictionary options) и передаваемый в него словарь параметров.

Словарь опций будет иметь этот ключ, если это локальное уведомление: UIApplication.LaunchOptionsLocalNotificationKey.

Если это удаленное уведомление, это будет UIApplication.LaunchOptionsRemoteNotificationKey.

Когда ключ LaunchOptionsLocalNotificationKey, объект имеет тип UILocalNotification. Затем вы можете посмотреть на уведомление и определить, какое именно это уведомление.

Совет: UILocalNotification не имеет идентификатора, так же, как и UNNotificationRequest. Поместите ключ словаря в UserInfo, содержащий requestId, чтобы при тестировании UILocalNotification у вас был конкретный requestId, на котором можно было бы основывать некоторую логику.

Я обнаружил, что даже на устройствах iOS 10+, которые при создании уведомлений о местоположении с помощью UNUserNotificationCenter AddNotificationRequest & UNMutableNotificationContent, что, когда приложение не запущено (я его убил), запускается нажатием на уведомление в центре уведомлений, что словарь все еще содержит объект UILocalNotificaiton.

Это означает, что мой код, который проверяет запуск на основе уведомлений, будет работать на устройствах iOS8 и iOS 10+

public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
    _logger.InfoFormat("FinishedLaunching");

    if(options != null)
    {
        if (options.ContainsKey(UIApplication.LaunchOptionsLocalNotificationKey))
        {
            //was started by tapping a local notification when app wasn't previously running.
            //works if using UNUserNotificationCenter.Current.AddNotificationRequest OR UIApplication.SharedApplication.PresentLocalNotificationNow);

            var localNotification = options[UIApplication.LaunchOptionsLocalNotificationKey] as UILocalNotification;

            //I would recommended a key such as this :
            var requestId = localNotification.UserInfo["RequestId"].ToString();
        }               
    }
    return true;
}

Ответ 11

если кто-то хочет ответить быстрым 3

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
    switch application.applicationState {
    case .active:
        //app is currently active, can update badges count here
        break
    case .inactive:
        //app is transitioning from background to foreground (user taps notification), do what you need when user taps here
        break
    case .background:
        //app is in background, if content-available key of your notification is set to 1, poll to your backend to retrieve data and update your interface here
        break
    default:
        break
    }
}

Ответ 12

Я начну с диаграммы состояний, которую я создал для своего собственного использования, чтобы более точно ее визуализировать и рассмотреть все другие состояния: https://docs.google.com/spreadsheets/d/e/2PACX-1vSdKOgo_F1TZwGJBAED4C_7cml0bEATqeL3P9UKpBwASlT6ZkUhhvglg6hkplt6Zkjhv5? GID = 0 & = одна истинная

Используя эту таблицу, мы можем увидеть, что на самом деле требуется для разработки надежной системы обработки уведомлений, которая работает практически во всех возможных случаях использования.

Полное решение ↓

  • Хранить полезные данные уведомлений в didReceiveRemoteNotification
  • Очистить сохраненные уведомления в applicationWillEnterForeground и didFinishLaunchingWithOptions
  • Для решения случаев, когда управляющий центр/центр уведомлений извлекается, вы можете использовать флаг willResignActiveCalled и изначально установить для него значение false, установите для этого параметра значение true в методе applicationWillResignActive,
  • В методе didReceiveRemoteNotification сохраняйте уведомления (userInfo) только в том случае, если willResignActiveCalled имеет значение false.
  • Сброс willResignActiveCalled в false в методе applicationDidEnterBackground и applicationDidBecomeActive.

Примечание. Аналогичный ответ предлагается в комментариях к ответу Эрика, однако лист состояния помогает найти все возможные сценарии, как я делал в своем приложении.

Пожалуйста, найдите полный код ниже и комментарий ниже, если какой-либо конкретный случай не обрабатывается:

AppDelegate

class AppDelegate: UIResponder, UIApplicationDelegate {
  private var willResignActiveCalled = false

  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    NotificationUtils.shared.notification = nil
    return true
  }
  func applicationWillResignActive(_ application: UIApplication) {
    willResignActiveCalled = true
  }
  func applicationDidEnterBackground(_ application: UIApplication) {
    willResignActiveCalled = false
  }
  func applicationWillEnterForeground(_ application: UIApplication) {
    NotificationUtils.shared.notification = nil
  }
  func applicationDidBecomeActive(_ application: UIApplication) {
    willResignActiveCalled = false
    NotificationUtils.shared.performActionOnNotification()
  }
  func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    if !willResignActiveCalled { // Check if app is in inactive by app switcher, control center, or notification center
      NotificationUtils.shared.handleNotification(userInfo: userInfo)
    }
  }
}

NotificationUtils: здесь вы можете написать весь свой код для навигации по различным частям приложения, обработки баз данных (CoreData/Realm) и выполнения всех других действий, которые необходимо выполнить при получении уведомления.

   class NotificationUtils {
  static let shared = NotificationUtils()
  private init() {}

  var notification : [AnyHashable: Any]?

  func handleNotification(userInfo : [AnyHashable: Any]){
    if UIApplication.shared.applicationState == UIApplicationState.active {
      self.notification = userInfo //Save Payload
      //Show inApp Alert/Banner/Action etc
      // perform immediate action on notification
    }
    else if UIApplication.shared.applicationState == UIApplicationState.inactive{
      self.notification = userInfo
    }
    else if UIApplication.shared.applicationState == UIApplicationState.background{
      //Process notification in background,
      // Update badges, save some data received from notification payload in Databases (CoreData/Realm)
    }
  }

  func performActionOnNotification(){
    // Do all the stuffs like navigating to ViewControllers, updating Badges etc
    defer {
      notification = nil
    }
  }
}

Ответ 13

Существует только один надежный способ, и он работает только для iOS 10+:

Использование UNUserNotificationCenter реализует метод UNUserNotificationCenterDelegate:

- (void) userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {

    //Here you can get your original push if you need to
    NSDictionary* pusDict = response.notification.request.content.userInfo;

    if ([response.actionIdentifier isEqualToString: UNNotificationDefaultActionIdentifier]) {
        //User tapped the notification
    } else if ([response.actionIdentifier isEqualToString: UNNotificationDismissActionIdentifier]) {
        //User dismissed the notification 
    } else if ([response.actionIdentifier isEqualToString: MYCustomActionId]) {
        //User chose my custom defined action
    }
    ...
}

Ответ 14

Прямо из документации для

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo:nil

Если приложение запущено и получает удаленное уведомление, приложение вызывает этот метод для обработки уведомления.

Ваша реализация этого метода должна использовать уведомление для принятия соответствующего курса действий.

И немного позже

Если приложение не запускается при поступлении push-уведомления, метод запускает приложение и предоставляет соответствующую информацию в словаре параметров запуска.

Приложение не вызывает этот метод для обработки этого push-уведомления.

Вместо этого ваша реализация

application:willFinishLaunchingWithOptions:

или

application:didFinishLaunchingWithOptions:

метод должен получить данные полезной нагрузки push-сообщения и отвечать соответствующим образом.

Ответ 15

Вы можете использовать:

-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo

для обработки уведомлений удаленного push.

Проверьте здесь documentation

Ответ 17

Для swift

 func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]){

    ++notificationNumber
    application.applicationIconBadgeNumber =  notificationNumber;

    if let aps = userInfo["aps"] as? NSDictionary {

        var message = aps["alert"]
        println("my messages : \(message)")

    }
}

Ответ 18

     // shanegao code in Swift 2.0
     func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject])
    {
            if ( application.applicationState == UIApplicationState.Inactive || application.applicationState == UIApplicationState.Background ){
                    print("opened from a push notification when the app was on background")
            }else{
                    print("opened from a push notification when the app was on foreground")
            }
    }

Ответ 19

Проблема с этим вопросом заключается в том, что "открытие" приложения не определено. Приложение запускается либо в холодном режиме из состояния неработоспособности, либо активируется из неактивного состояния (например, от перехода к нему из другого приложения). Здесь мое решение, чтобы отличить все эти возможные состояния:

typedef NS_ENUM(NSInteger, MXAppState) {
    MXAppStateActive = 0,
    MXAppStateReactivated = 1,
    MXAppStateLaunched = 2
};

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // ... your custom launch stuff
    [[MXDefaults instance] setDateOfLastLaunch:[NSDate date]];
    // ... more custom launch stuff
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    // Through a lot of trial and error (by showing alerts), I can confirm that on iOS 10
    // this method is only called when the app has been launched from a push notification
    // or when the app is already in the Active state.  When you receive a push
    // and then launch the app from the icon or apps view, this method is _not_ called.
    // So with 99% confidence, it means this method is called in one of the 3 mutually exclusive cases
    //    1) we are active in the foreground, no action was taken by the user
    //    2) we were 'launched' from an inactive state (so we may already be in the main section) by a tap
    //       on a push notification
    //    3) we were truly launched from a not running state by a tap on a push notification
    // Beware that cases (2) and (3) may both show UIApplicationStateInactive and cant be easily distinguished.
    // We check the last launch date to distinguish (2) and (3).

    MXAppState appState = [self mxAppStateFromApplicationState:[application applicationState]];
    //... your app logic
}

- (MXAppState)mxAppStateFromApplicationState:(UIApplicationState)state {
    if (state == UIApplicationStateActive) {
        return MXAppStateActive;
    } else {
        NSDate* lastLaunchDate = [[MXDefaults instance] dateOfLastLaunch];
        if (lastLaunchDate && [[NSDate date] timeIntervalSinceDate:lastLaunchDate] < 0.5f) {
            return MXAppStateLaunched;
        } else {
            return MXAppStateReactivated;
        }
    }
    return MXAppStateActive;
}

И MXDefaults - всего лишь небольшая оболочка для NSUserDefaults.

Ответ 20

func application(_ application: UIApplication, didReceiveRemoteNotification data: [AnyHashable : Any]) {
    print("Push notification received: \(data)")

    if let info = data["aps"] as? Dictionary<String, AnyObject> {
        let alertMsg = info["alert"] as! String
        print(alertMsg)
        switch application.applicationState {
        case .active:
            print("do stuff in case App is active")
        case .background:
            print("do stuff in case App is in background")
           // navigateToChatDetailViewControler(pushdata: data)
        case .inactive:
            print("do stuff in case App is inactive")
            // navigateToChatDetailViewControler(pushdata: data)
        }
    }
}

Ответ 21

Xcode 10 Swift 4.2

func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {

    let state : UIApplicationState = application.applicationState
    if (state == .Inactive || state == .Background) {
        // coming from background
    } else {
        // App is running in foreground
    }
}

Ответ 22

Для пользователей Swift:

Если вы хотите запустить другую страницу при открытии из push или что-то в этом роде, вам нужно проверить ее в didFinishLaunchingWithOptions как:

let directVc: directVC! = directVC(nibName:"directVC", bundle: nil)
let pushVc: pushVC! = pushVC(nibName:"pushVC", bundle: nil)

if let remoteNotification = launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey] as? NSDictionary {
     self.navigationController = UINavigationController(rootViewController: pushVc!)
} else {
     self.navigationController = UINavigationController(rootViewController: directVc!)
}
self.window!.rootViewController = self.navigationController

Ответ 23

В SWIFT:

Я запускаю Push Notifications (с извлечением фона). Когда мое приложение находится в фоновом режиме, и я получаю push-уведомление, я обнаружил, что didReceiveRemoteNotification в appDelegate будет вызываться дважды; один раз, когда уведомление получено, а другое - когда пользователь нажимает на уведомление.

Чтобы определить, было ли нажато уведомление о оповещении, просто проверьте, является ли исходное значение applicationState == 1 внутри didReceiveRemoteNotification в appDelegate.

func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject: AnyObject]) {
    // If not from alert click applicationState(1)
    if (application.applicationState.rawValue != 1) {
        // Run your code here
    }
}

Надеюсь, это поможет.

Ответ 24

Когда приложение находится в фоновом режиме как shanegao, вы можете использовать

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
    if ( application.applicationState == UIApplicationStateInactive || application.applicationState == UIApplicationStateBackground  )
    {
         //opened from a push notification when the app was on background
    }
}

Но если вы хотите запустить приложение и когда приложение закрыто, и вы хотите отладить ваше приложение, вы можете перейти на Изменить схему, а в меню слева выберите Выполнить и затем в запуске выберите Ожидание запуска исполняемого файла, а затем запуск приложения при нажатии на push-уведомление

Изменить схему > Выполнить > Ожидать запуска исполняемого файла

Ответ 25

Swift 3.0

В AppDelegate функция "didFinishLaunchingWithOptions" обрабатывает удаленное уведомление с некоторой задержкой и открывает ваш Viewcontroller. Вы можете использовать задержку для обработки уведомлений после успешной загрузки приложения.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

if let remoteNotification = launchOptions?[UIApplicationLaunchOptionsKey.remoteNotification] as! [NSObject : AnyObject]? {

            AppHelper.delay(0.8, closure: {
                self.handelNotification(dic: remoteNotification as! [String : Any])
            })
 }