Reputation: 1957
Is it possible to conditionally run code if the app is inactive
or in the background
.
These are the 2 scenarios:
Here is my code:
// Push notification received in background
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {
NSDictionary *userInfo = response.notification.request.content.userInfo;
[[SEGAnalytics sharedAnalytics] receivedRemoteNotification:userInfo];
if ([HSBeacon isBeaconPushNotification:userInfo]) {
UIApplication *applicaiton = [UIApplication sharedApplication];
// @todo Do not run if app was killed
if (application.applicationState == UIApplicationStateInactive || application.applicationState == UIApplicationStateBackground) {
NSString *helpScoutBeaconID = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"HelpScoutBeaconID"];
HSBeaconSettings *settings = [[HSBeaconSettings alloc] initWithBeaconId:helpScoutBeaconID];
[HSBeacon handlePushNotification:userInfo beaconSettings:settings];
}
// End of conditional code
}
completionHandler();
}
I've tried using:
UIApplication *applicaiton = [UIApplication sharedApplication];
if ( application.applicationState == UIApplicationStateInactive || application.applicationState == UIApplicationStateBackground) {
...
}
But this fires when the app is killed, inactive or in the backgorund.
Thanks
Upvotes: 1
Views: 1248
Reputation: 1957
Thanks @ScottPetit for you answer! I had to change a few things, but got it working with:
AppDelegate.h
// Use a local variable to determine if we deeplink to help scout chat
@property (nonatomic, assign) BOOL launchedFromPushNotification;
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
NSDictionary *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (notification) {
self.launchedFromPushNotification = YES;
} else {
self.launchedFromPushNotification = NO;
}
...
}
// Push notification received in foreground
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler{
self.launchedFromPushNotification = NO;
}
// Push notification received in background
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {
NSDictionary *userInfo = response.notification.request.content.userInfo;
if ([HSBeacon isBeaconPushNotification:userInfo] && !self.launchedFromPushNotification) {
NSString *helpScoutBeaconID = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"HelpScoutBeaconID"];
HSBeaconSettings *settings = [[HSBeaconSettings alloc] initWithBeaconId:helpScoutBeaconID];
[HSBeacon handlePushNotification:userInfo beaconSettings:settings];
self.launchedFromPushNotification = NO;
}
completionHandler();
}
Thanks for all your help!
Upvotes: 2
Reputation: 814
It feels like there must be a better way to do this, but one way that I think would work is keeping a local variable that you set in:
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler;
That delegate is only called if the application is currently in the foreground, so if you had a property like
@property (nonatomic, assign) BOOL receivedWillPresentNotification;
then you could potentially implement this like
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler {
// Whatever other logic you have here
self.receivedWillPresentNotification = YES;
}
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {
NSDictionary *userInfo = response.notification.request.content.userInfo;
[[SEGAnalytics sharedAnalytics] receivedRemoteNotification:userInfo];
if ([HSBeacon isBeaconPushNotification:userInfo] && self.receivedWillPresentNotification) {
NSString *helpScoutBeaconID = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"HelpScoutBeaconID"];
HSBeaconSettings *settings = [[HSBeaconSettings alloc] initWithBeaconId:helpScoutBeaconID];
[HSBeacon handlePushNotification:userInfo beaconSettings:settings];
}
self.receivedWillPresentNotification = NO;
completionHandler();
}
Again there's probably a better solution, related to checking for notifications in applicationDidFinishLaunching
and checking the state of the application there that you could then store, but I think you could potentially use the other UNUserNotificationCenterDelegate
methods as a proxy.
Upvotes: 1