检测是否通过推送通知启动/打开了应用程序

时间:2013-05-06 07:05:05

标签: ios push-notification ios6 apple-push-notifications uiapplicationdelegate

是否可以知道应用是否是通过推送通知启动/打开的?

我想这里可以发现启动事件:

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

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

    }
}

但是,当应用程序处于后台时,如何检测到它是通过推送通知打开的?

30 个答案:

答案 0 :(得分:177)

请参阅此代码:

- (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

答案 1 :(得分:123)

迟到但也许有用

当应用未运行时

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

被称为..

你需要检查推送通知

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");
}

答案 2 :(得分:27)

我们遇到的问题是在启动应用后正确更新视图。这里有复杂的生命周期方法序列令人困惑。

生命周期方法

我们对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

问题

好的,现在我们需要:

  1. 确定用户是否通过推送打开应用
  2. 根据推送状态更新视图
  3. 清除状态,以便后续打开不会将用户返回到相同位置。
  4. 棘手的是,当应用程序实际变为活动状态时,必须更新视图,这在所有情况下都是相同的生命周期方法。

    我们的解决方案草图

    以下是我们解决方案的主要组成部分:

    1. 在AppDelegate上存储notificationUserInfo实例变量。
    2. notificationUserInfo = nilapplicationWillEnterForeground中设置didFinishLaunchingWithOptions
    3. notificationUserInfo = userInfo
    4. 中设置didReceiveRemoteNotification:inactive
    5. applicationDidBecomeActive始终调用自定义方法openViewFromNotification并传递self.notificationUserInfo。如果self.notificationUserInfo为nil,则提前返回,否则根据self.notificationUserInfo中的通知状态打开视图。
    6. <强>解释

      当从didFinishLaunchingWithOptionsapplicationWillEnterForeground打开时,总是在didReceiveRemoteNotification:inactive之前立即调用,因此我们首先在这些方法中重置notificationUserInfo,这样就没有陈旧状态。然后,如果调用了didReceiveRemoteNotification:inactive,我们知道我们已经从推送中打开,因此我们设置self.notificationUserInfo然后由applicationDidBecomeActive选中,以将用户转发到右侧视图。< / p>

      最后一种情况是,如果用户在应用切换器中打开了应用程序(即,当应用程序位于前台时双击主页按钮),然后接收推送通知。在这种情况下,只调用didReceiveRemoteNotification:inactive,并且WillEnterForeground和didFinishLaunching都不会被调用,所以你需要一些特殊的状态来处理这种情况。

      希望这有帮助。

答案 3 :(得分:23)

这是一个很好的帖子......但它仍然缺少问题的实际解决方案(正如各种评论中所指出的那样)。

  

原始问题是关于检测应用启动的时间   / 打开来自推送通知,例如用户点按   通知。这些答案实际上都没有涵盖这种情况。

当通知到达时,可以在呼叫流程中看到原因application:didReceiveRemoteNotification...

当用户点击通知时,再次收到 AND 通知时会调用

。因此,您只能通过查看用户点击它的UIApplicationState来判断。

此外,您不再需要在application:didFinishLaunchingWithOptions...中处理应用程序的“冷启动”情况,因为在iOS 9+(也可能是8)启动后再次调用application:didReceiveRemoteNotification...

那么,如何判断用户是否启动了事件链?我的解决方案是标记应用程序开始退出后台或冷启动的时间,然后在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也很好。

答案 4 :(得分:18)

Swift 2.0 For&#39; Not Running&#39;州(本地和远程通知)

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

}

答案 5 :(得分:15)

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");
    }
}

答案 6 :(得分:15)

当应用终止时,用户点击推送通知

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

当应用处于后台时,用户点击推送通知

  

如果用户从系统显示的提醒中打开您的应用,系统可能会再次调用此方法当您的应用即将进入前台时,以便您可以更新用户界面并显示信息与通知有关。

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

根据您的应用,它还可以通过content-available内的aps向您发送静音推送,因此请注意这一点:)请参阅https://stackoverflow.com/a/33778990/1418457

答案 7 :(得分:12)

对于swift:

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

    }

}

答案 8 :(得分:3)

是的,您可以通过 appDelegate

中的此方法进行检测
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
      /* your Code*/
}

对于本地通知:

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

答案 9 :(得分:3)

为Xamarin用户发布此内容。

检测应用是否是通过推送通知启动的关键是AppDelegate.FinishedLaunching(UIApplication app, NSDictionary options)方法,以及传入的选项字典。

如果选项字典是本地通知,则会在其中包含此密钥:UIApplication.LaunchOptionsLocalNotificationKey

如果是远程通知,则为UIApplication.LaunchOptionsRemoteNotificationKey

当密钥为LaunchOptionsLocalNotificationKey时,对象的类型为UILocalNotification。 然后,您可以查看通知并确定它是哪个特定通知。

专业提示:UILocalNotification中没有标识符,与UNNotificationRequest的方式相同。在包含requestId的UserInfo中放置一个字典键,以便在测试UILocalNotification时,您可以根据某些逻辑使用特定的requestId。

我发现即使在iOS 10+设备上使用UNUserNotificationCenter&#39; AddNotificationRequest&amp; 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;
}

答案 10 :(得分:2)

如果有人想在swift 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
    }
}

答案 11 :(得分:2)

只有一种可靠的方法,并且仅适用于 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
    }
    ...
}

答案 12 :(得分:2)

我将从我为自己创建的状态图开始,以更准确地可视化并考虑所有其他状态: https://docs.google.com/spreadsheets/d/e/2PACX-1vSdKOgo_F1TZwGJBAED4C_7cml0bEATqeL3P9UKpBwASlT6ZkU3iLdZnOZoevkMzOeng7gs31IFhD-L/pubhtml?gid=0&single=true

使用此图表,我们可以看到实际需要什么才能开发出适用于几乎所有可能用例的强大通知处理系统。

完整解决方案↓

  • 通知有效负载存储在 didReceiveRemoteNotification
  • 清除 applicationWillEnterForeground didFinishLaunchingWithOptions
  • 中存储的通知
  • 要解决控制中心/通知中心拉动的情况,您可以使用标记 willResignActiveCalled 并将其设置为 false applicationWillResignActive 方法中将此设置为 true
  • didReceiveRemoteNotification 方法中,仅当willResignActiveCalled为false时才保存通知(userInfo)。
  • applicationDidEnterBackground applicationDidBecomeActive 方法中重置 willResignActiveCalled为false

注意:在对Eric的回答的评论中提出了类似的答案,但是,状态表有助于像我在我的应用程序中那样找到所有可能的场景。

如果没有处理任何特定情况,请查看下面的完整代码并在下面发表评论:

<强>的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 :(得分:1)

M.Othman的答案对于不包含场景委托的应用是正确的 对于场景代理应用,这在 iOS 13

上对我有用

以下是应在将连接场景

中编写的代码
if connectionOptions.notificationResponse == nil { 
//Not opened from push notification
} else {
  //Opened from push notification
}

应用程序委托代码以支持早期版本 didFinishLaunchingWithOptions

let notification = launchOptions?[UIApplication.LaunchOptionsKey.remoteNotification]
        if (notification != nil) {

            //Launched from push notification
        } else {

            //Launch from other source
        }

答案 14 :(得分:1)

直接来自

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

如果应用程序正在运行并收到远程通知,则应用程序会调用此方法来处理通知。

您对此方法的实施应使用通知采取适当的措施。

稍后

如果推送通知到达时应用程序未运行,该方法将启动应用程序并在启动选项字典中提供相应的信息。

该应用不会调用此方法来处理该推送通知。

相反,你的

的实现
application:willFinishLaunchingWithOptions:

application:didFinishLaunchingWithOptions:

方法需要获取推送通知有效负载数据并做出适当的响应。

答案 15 :(得分:0)

我还没试过但也许你可以给自己发一个通知吗? http://nshipster.com/nsnotification-and-nsnotificationcenter/

答案 16 :(得分:0)

2021,Swift 5,仅限本地通知

UNUserNotificationCenter.current().delegate = self

extension YourClass: UNUserNotificationCenterDelegate {

    func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {
        let notificationIdentifier = response.notification.request.identifier

        // If this is called, then your app was opened from a local notification with this identifier
    }
}


答案 17 :(得分:0)

M.Othman 对 Swift 5 的回答。(虽然使用 NSLog 是 not recommended anymore

在设置显示 RootViewController 所需的所有内容后添加以下内容。在您的 application(_:didReceiveRemoteNotification) 中,您应该添加可以区分首次启动和后台启动类型的逻辑。

if let launchOptions = launchOptions, 
let notification = launchOptions[UIApplicationLaunchOptionsKey.remoteNotification] 
as? [AnyHashable : Any] {
    NSLog("app recieved notification from remote \(notification)")
    self.application(application, didReceiveRemoteNotification: notification)
} else {
    NSLog("app did not recieve notification")
}

可以在以下位置找到一些其他的 Swift 特定答案:How to handle launch options in Swift 3 when a notification is tapped? Getting syntax problems

答案 18 :(得分:0)

如果您运行的是 iOS 13 或更高版本,请在您的 SceneDelegate:

中使用以下代码
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
    
    guard let notificationResponse = connectionOptions.notificationResponse else { return }
    
    let pushTitle = notificationResponse.notification.request.content.title
    let pushSubtitle = notificationResponse.notification.request.content.subtitle
    let pushBody = notificationResponse.notification.request.content.body
    
    // do your staff here
}

答案 19 :(得分:0)

对于iOS 10+,无论应用程序的状态如何,您都可以使用此方法来知道何时单击通知。

func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {

    //Notification clicked
    completionHandler()
}

答案 20 :(得分:0)

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
    }
}

答案 21 :(得分:0)

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)
        }
    }
}

答案 22 :(得分:0)

     // shanegao's 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")
            }
    }

答案 23 :(得分:0)

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)")

    }
}

答案 24 :(得分:0)

这个问题的问题是“打开”应用程序的定义不明确。应用程序要么从未运行状态冷启动,要么从非活动状态重新激活(例如从另一个应用程序切换回它)。这是我区分所有这些可能状态的解决方案:

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's 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的一个小包装。

答案 25 :(得分:0)

您可以使用:

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

处理远程推送通知。

点击documentation

答案 26 :(得分:-1)

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])
            })
 }

答案 27 :(得分:-1)

当app在后台作为 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
    }
}

但是,如果你想启动应用程序,当应用程序关闭并且你想调试你的应用程序时,你可以转到编辑方案,然后在左侧菜单中选择运行,然后在启动时选择等待可执行文件启动,然后在单击推送通知时启动应用程序

编辑方案&gt;运行&gt;等待可执行文件启动

答案 28 :(得分:-1)

对于Swift用户:

如果您想要在推送或其他类似的东西上启动其他页面,则需要在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

答案 29 :(得分:-1)

IN SWIFT:

我正在运行推送通知(带背景提取)。当我的应用程序在后台并收到推送通知时,我发现appDelegate中的didReceiveRemoteNotification将被调用两次;一次用于收到通知,另一次用于点击通知提醒时。

要检测是否单击了通知警报,只需检查appDelegate中didReceiveRemoteNotification中的applicationState原始值== 1。

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

我希望这会有所帮助。