首页 文章

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

提问于
浏览
144

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

我猜这个发布活动可以在这里找到:

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

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

    }
}

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

24 回答

  • 12

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

  • 13

    请参阅此代码:

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

    迟到但也许有用

    当应用程序未运行时

    (BOOL)应用程序:(UIApplication *)应用程序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");
    }
    
  • 15

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

    Lifecycle Methods

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

    The problem

    好的,现在我们需要:

    • 确定用户是否通过推送打开应用程序

    • 根据推送状态更新视图

    • 清除状态,以便后续打开不会将用户返回到相同位置 .

    棘手的是,当应用程序实际变为活动状态时,必须更新视图,这在所有情况下都是相同的生命周期方法 .

    Sketch of our solution

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

    • 在AppDelegate上存储 notificationUserInfo 实例变量 .

    • applicationWillEnterForegrounddidFinishLaunchingWithOptions 中设置 notificationUserInfo = nil .

    • didReceiveRemoteNotification:inactive 中设置 notificationUserInfo = userInfo

    • applicationDidBecomeActive 始终调用自定义方法 openViewFromNotification 并传递 self.notificationUserInfo . 如果 self.notificationUserInfo 为nil则提前返回,否则根据 self.notificationUserInfo 中找到的通知状态打开视图 .

    Explanation

    当从 didFinishLaunchingWithOptionsapplicationWillEnterForeground 开始打开时,总是在 didReceiveRemoteNotification:inactive 之前立即调用,所以我们首先在这些方法中重置notificationUserInfo,这样就没有陈旧状态了 . 然后,如果 didReceiveRemoteNotification:inactive 被调用,我们知道我们正在从推动开始,所以我们设置 self.notificationUserInfo 然后由 applicationDidBecomeActive 选中以将用户转发到右视图 .

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

    希望这可以帮助 .

  • 171

    这是一个很好的帖子...但它仍然缺少问题的实际 solution (如各种评论中所指出的) .

    最初的问题是关于检测应用程序何时从推送通知启动/打开,例如用户点击通知 . 这些答案实际上都没有涵盖这个案例 .

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

    当用户点击通知时再次收到通知 AND 时调用 . 因此,你只能通过查看 UIApplicationState 来判断用户是否点击它 .

    此外,您不再需要在 application:didFinishLaunchingWithOptions... 中处理应用程序'cold start'的情况,因为在iOS 9中启动后再次调用 application:didReceiveRemoteNotification... (也可能是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也很好 .

  • 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")
                }
        }
    
  • 0

    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
    

    }

  • 0

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

    When app is terminated, and user taps on push notification

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

    When app is in background, and user taps on push notificaion

    如果用户从系统显示的警报中打开您的应用程序,系统可能会在您的应用程序即将进入前台时再次调用此方法,以便您可以更新用户界面并显示与通知相关的信息 .

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

    根据您的应用程序,它也可以在 aps 内向 content-available 发送静音推送,所以请意识到这一点:)见https://stackoverflow.com/a/33778990/1418457

  • 115

    For 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
    
        }
    
    }
    
  • 3

    是的,您可以通过 appDelegate 中的此方法进行检测:

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

    对于本地通知:

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

    如果有人想要快速回答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
        }
    }
    
  • 0

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

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

    Complete solution ↓

    • didReceiveRemoteNotification 中存储 notification 有效负载

    • Clear 已在 applicationWillEnterForegrounddidFinishLaunchingWithOptions 中存储通知

    • 要处理控制中心/通知中心拉动的情况,您可以使用标志 willResignActiveCalled 并将其初始设置为 false ,在 applicationWillResignActive 方法中将其设置为 true

    • didReceiveRemoteNotification 方法中,仅当willResignActiveCalled为false时才保存通知(userInfo) .

    • applicationDidEnterBackgroundapplicationDidBecomeActive 方法中重置 willResignActiveCalled to 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
        }
      }
    }
    
  • 0

    只有一种可靠的方法,它只适用于 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
        }
        ...
    }
    
  • 2

    直接从文档中获取

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

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

    您对此方法的实现应使用通知采取适当的操作过程 .

    过了一会儿

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

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

    相反,你的实施

    application:willFinishLaunchingWithOptions:
    

    要么

    application:didFinishLaunchingWithOptions:
    

    方法需要获取推送通知有效负载数据并进行适当响应 .

  • -1

    您可以使用:

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

    处理远程推送通知 .

    点击这里documentation

  • 17

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

    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 的一个小包装 .

  • 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)")
    
        }
    }
    
  • 0

    当应用程序在后台作为 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
        }
    }
    

    但是如果你想启动应用程序并且当应用程序关闭并且你想调试应用程序时你可以转到 Edit Scheme 并在左侧菜单中选择 Run 然后在启动时选择 Wait for executable to be launched 然后在你点击推送通知时启动应用程序

    Edit Scheme > Run > Wait for executable to be launched

  • 2

    为Xamarin用户发布此信息 .

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

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

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

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

    专业提示: UILocalNotification 中没有标识符,与 UNNotificationRequest 的方式相同 . 在包含requestId的UserInfo中放置一个字典键,这样在测试 UILocalNotification 时,您将有一个特定的requestId可用于基于某些逻辑 .

    我发现即使在iOS 10设备上使用 UNUserNotificationCenterAddNotificationRequestUNMutableNotificationContent 创建位置通知时,当应用程序未运行时(我将其杀死),并通过点击通知中心的通知启动,即字典仍然包含 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;
    }
    
  • -1
    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

    对于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
    
  • 22

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

    我希望这有帮助 .

  • 0

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

相关问题