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

Posted

技术标签:

【中文标题】在应用程序终止后使用 NSNotification 处理 UIViewController 中的 UILocalNotification【英文标题】:Handle UILocalNotification in UIViewController using NSNotification after the app has been terminated 【发布时间】:2013-11-23 16:07:12 【问题描述】:

我正在与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: 方法在我的UIViewControllerviewDidLoad 之前调用。然后在PostNotificationName 之后创建观察者,然后观察者什么也没有收到。

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

我知道didFinishLaunchingWithOptions 方法是在didlocalNotificationReceived 之前调用的,所以那里可能有一些事情要做。

更新:

我还发现应用程序何时终止。点击通知后,它会打开应用程序,调用函数didFinishLaunchingWithOptions,但不要调用didReceiveLocalNotification。所以我想我会以不同的方式处理这两种情况。

【问题讨论】:

尝试在 didDinishLaunching 中强制加载视图(通过访问视图属性)。看看有没有帮助。 【参考方案1】:

好的,我找到了答案。

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

appDelegate 中的 didFinishLaunchingWithOptions: 方法如下所示:

- (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 中,我在initWithCoder: 方法而不是viewDidLoad: 中创建NSNotification 观察者

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

我不确定这是否是最佳做法。但是效果很好!

希望它会有所帮助:)

【讨论】:

它的工作让我太棒了!!谢谢,你节省了我的时间!! :)

以上是关于在应用程序终止后使用 NSNotification 处理 UIViewController 中的 UILocalNotification的主要内容,如果未能解决你的问题,请参考以下文章

IOS NSNotification Center 通知中心的使用

iOS 通知(NSNotification)

NSNotification的使用 & 和代理的区别

对由 NSTimer 异步发送的 NSNotification 进行单元测试

键入“NSNotification.Name?”没有成员“firInstanceIDTokenRefresh”

关于iOS开发中NSNotification