应用程序终止后无法处理本地通知

时间:2015-01-12 11:24:42

标签: ios iphone xcode swift notifications

我制作的应用程序会跟踪目标和里程碑(属于目标)并通过UILocalNotification提醒用户何时达到目标或里程碑的截止日期

当应用处于后台状态且应用位于前台时,我的应用已成功处理本地通知。

我知道如果你想在应用程序终止时收到本地通知,你需要通过应用程序的启动选项访问本地通知:appDelegate中的didFinishLaunchingWithOptions:方法。

然而,每当我在应用程序终止后测试应用程序并激活本地通知时,我无法处理应用程序中的本地通知:didFinishLaunchingWithOptions:

我怀疑它与启动选项为nil或启动选项没有本地通知有效负载有关。

我测试这种情况的方式是这样的:

  1. 我构建并运行应用程序(命令+ R)
  2. 我安排通知
  3. 我停止运行模拟器,然后将我的mac时间更改为just 在开火日期之前
  4. 我再次构建并运行应用程序,然后继续终止应用程序 从模拟器(通过shift + command + h两次然后 向上滑动)
  5. 我锁定了屏幕并等待通知
  6. 点火后我在锁定屏幕上滑动通知
  7. 通知触发后,我轻扫通知,启动应用程序,但我在处理应用程序中的本地通知有效负载时使用的方法:didFinishLaunchingWithOptions:不会被调用。

    我的应用程序中的代码:didFinishLaunchingWithOptions:处理本地通知的有效负载如下:

     if let options = launchOptions {
            let value = options[UIApplicationLaunchOptionsLocalNotificationKey] as? UILocalNotification
    
            if let notification = value {
                self.application(application, didReceiveLocalNotification: notification)
            }
        }
    

    我的应用程序中的代码:didReceiveLocalNotification:如下:

        func application(application: UIApplication, didReceiveLocalNotification notification: UILocalNotification) {
        //If the user receives a notification while app is in the foreground
        println("")
    
        if application.applicationState == UIApplicationState.Active {
            println("did receive notification")
            UIApplication.sharedApplication().applicationIconBadgeNumber = 0
            let alertController = UIAlertController(title: nil, message: notification.alertBody!, preferredStyle: UIAlertControllerStyle.Alert)
    
            let alertAction = UIAlertAction(title: "View", style: UIAlertActionStyle.Default) { (alertAction) -> Void in
            self.performFollowUpActionForNotification(notification)
            }
    
            let cancelAction = UIAlertAction(title: "Close", style: UIAlertActionStyle.Cancel, handler: nil)
    
            alertController.addAction(alertAction)
            alertController.addAction(cancelAction)
    
            self.window!.rootViewController!.presentViewController(alertController, animated: true, completion: nil)
        }
    
        else {
            performFollowUpActionForNotification(notification)
            application.applicationIconBadgeNumber = 0
        }
    
    
    }
    

    以及辅助方法performFollowUpActionForNotification:

    func performFollowUpActionForNotification(notification:UILocalNotification) {
    
        if notification.alertAction! == "View Goal" {
            if let tabVC = self.window?.rootViewController? as? UITabBarController {
                let navCon = tabVC.viewControllers![0] as UINavigationController
                if navCon.topViewController is GoalPageViewController {
    
                }
    
                else {
                    navCon.pushViewController(navCon.viewControllers![0] as UIViewController, animated: true )
    
                }
            }
        }
    
        if notification.alertAction! == "View Milestone" {
            if let tabVC = self.window?.rootViewController? as? UITabBarController {
    
                let navCon = tabVC.viewControllers![0] as UINavigationController
                if let goalPageVC = navCon.viewControllers![0] as? GoalPageViewController {
                    goalPageVC.findGoalThatContainsMilestoneAndGoToDetailForNotification(notification)
                }
                else {println("cant down cast view controller to goal page view controller")}
            }
        }
    }
    

    我的代码存在问题,或者我是如何针对此方案测试我的应用的?我迫切需要一个答案。

1 个答案:

答案 0 :(得分:3)

希望这对您有所帮助,请看下面。

在iOS 7.1中,Apple对系统如何处理信标触发的通知进行了非常重要的更新。现在,应用程序可以在进入/退出监视事件发生时采取操作,即使它已被终止。与iOS 7相比,这是一个惊人的改进,但是它仍然存在很多关于它如何工作的混淆,所以我们准备了一个简短的教程。

位置事件(在这种情况下与信标相关)的处理方式与任何其他应用程序启动事件的处理方式相同。当应用程序终止时,每次手机都会进入或退出beacon的区域,它将自动启动并且应用程序:didFinishLaunchingWithOptions:方法(AppDelegate类)使用launchOptions参数中存在的UIApplicationLaunchOptionsLocationKey键进行调用。

当您验证此密钥存在时(因此位置是您的应用程序启动的原因)您应该创建ESTBeaconManager类的新实例,将委托设置为AppDelegate对象(或任何其他作为ESTBeaconManagerDelegate的对象,并在此之前创建事件发生)并开始监控。传递给startMonitoringForRegion:方法的区域并不重要,因为ESTBeaconManager委托将接收最新的区域信息。您可以选择在iOS中注册的应用程序中的任何一个。当监视被撤销时,app将自动接收beaconManager中的最近进入/退出区域事件:didEnterRegion:或beaconManager:didExitRegion:method。

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

{ 

   if([launchOptions objectForKey:@"UIApplicationLaunchOptionsLocationKey"])
   {
    self.beaconManager = [ESTBeaconManager new];
    self.beaconManager.delegate = self;
    // don't forget the NSLocationAlwaysUsageDescription in your Info.plist
    [self.beaconManager requestAlwaysAuthorization];
    [self.beaconManager startMonitoringForRegion:[[ESTBeaconRegion alloc]
                                                  initWithProximityUUID:ESTIMOTE_PROXIMITY_UUID
                                                  identifier:@"AppRegion"]];

    }

   return YES;

    }

 -(void)beaconManager:(ESTBeaconManager *)manager didEnterRegion:(ESTBeaconRegion *)region

{

 UILocalNotification *notification = [[UILocalNotification alloc] init];
 notification.alertBody = @"Enter region";
 notification.soundName = UILocalNotificationDefaultSoundName;

 [[UIApplication sharedApplication] presentLocalNotificationNow:notification];

}

-(void)beaconManager:(ESTBeaconManager *)manager didExitRegion:(ESTBeaconRegion *)region
{
  UILocalNotification *notification = [[UILocalNotification alloc] init];
  notification.alertBody = @"Exit region";
  notification.soundName = UILocalNotificationDefaultSoundName;

 [[UIApplication sharedApplication] presentLocalNotificationNow:notification];
}