应用程序终止后,使用NSNotification处理UIViewController中的UILocalNotification

时间:2013-11-23 16:07:12

标签: ios uiviewcontroller uilocalnotification nsnotificationcenter nsnotifications

我正在使用UILocalNotification,我想通知我的某个控制器,即使该应用已被终止,也已收到通知。

在我的appDelegate中,我实现了这个功能:

-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
    if ([application applicationState] == UIApplicationStateInactive) {
        [[NSNotificationCenter defaultCenter] postNotificationName:@"localNotificationReceived" object:notification.userInfo];
    }
}

在我的UIViewController我在viewDidLoad方法

上实施了观察者
- (void)viewDidLoad
{
    [super viewDidLoad];

    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didlocalNotificationReceived:) name:@"localNotificationReceived" object:nil];   

}

当应用在后台运行时,它非常有效。由于已经调用viewDidLoad方法并且Observer正在等待..

问题是我杀了应用程序。然后我的控制器的观察者走了,永远不会调用didlocalNotificationReceived方法。

我认为这是因为当我收到localNotification并再次运行应用时。在didReceiveLocalNotification:的{​​{1}}之前调用viewDidLoad方法。然后在UIViewController之后创建观察者,然后观察者什么也得不到。

我想知道是否有一些最佳实践或模式来处理这类问题。

我知道在PostNotificationName之前调用didFinishLaunchingWithOptions方法,所以可能会有一些事情要做。

更新:

我还发现app何时被终止。点击通知后,它会打开应用,调用函数didlocalNotificationReceived,但从不致电didFinishLaunchingWithOptions。所以我认为我会以不同的方式处理这两种情况。

1 个答案:

答案 0 :(得分:2)

好的,我找到了答案。

我实际上是手动初始化我的故事板,并且在发布NSNotification之前要小心我初始化主视图

我的didFinishLaunchingWithOptions:中的appDelegate方法看起来像这样:

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

    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:[NSBundle mainBundle]];
    UIViewController *vc =[storyboard instantiateInitialViewController]; //call the initWithCoder: method of my controller

    if (launchOptions[UIApplicationLaunchOptionsLocalNotificationKey]) {
        UILocalNotification *localNotification = launchOptions[UIApplicationLaunchOptionsLocalNotificationKey];
        [[NSNotificationCenter defaultCenter] postNotificationName:@"localNotificationReceived" object:localNotification.userInfo];
    }

    self.window.rootViewController = vc;
    [self.window makeKeyAndVisible];

    return YES;
}

然后在我的UIViewController中,我使用NSNotification方法而不是initWithCoder:

创建viewDidLoad:观察者
- (instancetype)initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    if (self) {
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didlocalNotificationReceived:) name:@"localNotificationReceived" object:nil];
    }
    return self;
}

- (void)didlocalNotificationReceived:(NSNotification *)notification
{
    //Execute whatever method when received local notification
}

当应用程序未被杀死时,我仍然使用didReceiveLocalNotification:方法:

-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
    if ([application applicationState] == UIApplicationStateInactive) {
        [[NSNotificationCenter defaultCenter] postNotificationName:@"localNotificationReceived" object:notification.userInfo];
    }
}

我不确定这是不是最好的做法。但它运作良好!

希望它会有所帮助:)