IOS:Call method when local notification is received in background - objective-c

I know this question looks duplicate but i did not found the exact answer as per my requirement.Doing app related to medical events with Below steps followed
1) connected the app to smart watch.
2) schedule the local notifications i. e when user needs to take
medicine
3) when the schedule time arrives local notification fires and
delegate method is calling (did receive local notification)
4) At the time of firing local notifications i am sending
message(sms) to the user from the app that he has to take certain
medicine
Everything is working fine when the app is in foreground and when the app reaches to background only local notifications are firing no message is received by the user.Because no method is calling when the app is in background.But my whole application use case mostly depends on sending sms.
Is there any solution for this ? Any help will be welcomed !! Thnxx !!

You're going to need to explicitly run your method in a UIBackgroundTask. See example below:
UIApplication * application = [UIApplication sharedApplication];
UIBackgroundTaskIdentifier background_task;
background_task = [application beginBackgroundTaskWithExpirationHandler:^ {
[application endBackgroundTask: background_task];
background_task = UIBackgroundTaskInvalid;
}];
// your method call here
[application endBackgroundTask: background_task];
background_task = UIBackgroundTaskInvalid;
I'm doing something similar and this works for me. Let me know if thats not working for you.

Related

IOS:call did receive remote notification delegate when app is in background

My app contains push notification functionality and i have done the part of coding to receive push notification in my application.When my app enters to background i am receiving push notifications and when i click push notification button app come to foreground and calling did receive remote notification delegate method.I need to call the same delegate method when my app receives push notification in background but without opening the app by clicking push notification button on the top of the screen.I have written code as below.
if ([application respondsToSelector:#selector(registerUserNotificationSettings:)])
{
UIUserNotificationType userNotificationTypes = (UIUserNotificationTypeAlert |
UIUserNotificationTypeBadge |
UIUserNotificationTypeSound);
UIUserNotificationSettings *settings = [UIUserNotificationSettings
settingsForTypes:userNotificationTypes
categories:nil];
[application registerUserNotificationSettings:settings];
[application registerForRemoteNotifications];
}
else
{
// Register for Push Notifications, if running iOS version < 8
[application registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |
UIRemoteNotificationTypeAlert |
UIRemoteNotificationTypeSound)];
}
if ([application respondsToSelector:#selector(registerUserNotificationSettings:)]) {
[application registerUserNotificationSettings:[UIUserNotificationSettings
settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge
|UIUserNotificati
onTypeSound categories:nil]];
}
My final intension is to call did receive remote notification when app is in background also.
The didReceiveRemoteNotification delegate won't be invoked when the app is closed or in background.When you tap on the notification,it launches the app and the method will be invoked.You can do required action at this moment like decrementing the icon badge.This is the working flow of push notification in iOS.One more thing is when the app is closed and you are taping on notification,didReceiveRemoteNotification won't be invoked.ApplicationDidFinishLaunching will be called and you can identify there using launchoption dictionary whether its launched from notification
If App receives Notification in background & user will open app without tapping on notification than that notification will not be received at all.
To achieve this you need to try different thing.
Here is an idea that might help you:
When Notification pushed from the server & received successfully in App you can send message through Api that it received.
Now if in above case where notification not received in the app server will not get the successful receive message. So in this case it can be saved at server in pending notifications table.
Now once you open up the device 1 api will check if any pending notifications on the server & if found than will get that in response & after that it will be removed from the server.
Note: Its an idea that is tried earlier & working. You can improve it as per your requirement.
Hope it will work for you.

iOS 6 local notifications fail when the phone is locked with app open

I have an app with basic alarm functionality. In my applicationWillResignActive: method I have it setup to create notifications to set off the alarm. This works pretty great, and I believe this is the proper way to do it (let me know if you think there is a better way).
Only in the specific situation, ONLY ON iOS 6, when the application is not "quit" (the home button is never pressed) but the user merely locks the phone or the phone auto locks, the notifications don't go off.
I have traced through the code, and the notifications are indeed being created and it worked perfectly in iOS 5.
Here is my code:
- (void)applicationWillResignActive:(UIApplication *)application
{
[UIApplication sharedApplication].idleTimerDisabled = NO;
[alarm setupForBackground];
if ([alarm isRunning]) {
[alarm stop];
}
}
Here is the notification creation method:
- (void)setupForBackground
{
UILocalNotification* alarmNotification = [[UILocalNotification alloc] init];
if (alarmNotification) {
alarmNotification.fireDate = alarmDate;
alarmNotification.timeZone = [NSTimeZone defaultTimeZone];
alarmNotification.repeatInterval = 0;
alarmNotification.soundName = #"NotificationSound.aif";
[[UIApplication sharedApplication] scheduleLocalNotification:alarmNotification];
}
}
I have been searching for an answer for a while, and I could not find anything stating something about notification changes. Thanks for any help.
I have a semi-solution. Apparently if you add an AlertBody to the notification, then it works.
My belief is that this is a bug in iOS 6. As I mentioned it worked in iOS 5, the documentation makes no mention of having such a requirement, and the notification does work without the AlertBody if the application is quit (the home button is pressed).
Still curious to see if my understanding is correct and if I should file a bug report with Apple.
Thoughts anybody?

iOS Handle notifications after starting app from not-running state

I've been trying to handle receiving notifications in my app, but its not really working out.
When I use didReceiveLocalNotification:(UILocalNotification *)notification. I can receive and use the notification that is used to enter the app, without any problems
However, this function is only fired when the app is already running (active, inactive, background, and possibly suspended, but I haven't tried that yet).
Now, there is this function didFinishLaunchingWithOptions:(NSDictionary *)launchOptions where you can use [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey] which would return a UILocalNotification.
However, when you launch the app from not-running state, this event is not fired. The LocalNotification then opens the app, but I can not use it in any way.
Now, my question is: How can I make it work, so I can receive and process notifications when starting the app, from a notification, when the app is in not-running state? Is there perhaps something I'm doing wrong here?
Here is a bit of sample code from my app:
First, the didFinishLaunchingWithOptions function, which, unfortunatly does not work. The function [sharedLocalNotificationsInstance processNotification:notification] is never launched...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
LocalNotificationsController *sharedLocalNotificationsInstance = [LocalNotificationsController sharedLocalNotificationsInstance];
[sharedLocalNotificationsInstance checkNotifications];
UILocalNotification *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if ( notification != nil ) {
// Process the received notification
[sharedLocalNotificationsInstance processNotification:notification];
application.applicationIconBadgeNumber = 0;
}
return YES;
}
And a second piece of code: The didReceiveLocalNotification function, which works perfectly: I receive the notification, and [sharedLocalNotificationsInstance processNotification:notification] works perfectly.
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification{
// Used when the application launches from a notification
LocalNotificationsController *sharedLocalNotificationsInstance = [LocalNotificationsController sharedLocalNotificationsInstance];
// Process the received notification
[sharedLocalNotificationsInstance processNotification:notification];
}
This is how iOS handles local notification. It depends on which state of your app, e.g. active, running in background, or not started yet. The iOS will invoke either didFinishLaunchingWithOptions or didReceiveLocalNotification, or won't touch your app at all.
Please see this article for clarification - http://www.thekspace.com/home/component/content/article/62-uilocalnotification-demystified.html
<Matrix-Morpheus-Meme title="WHAT IF I TOLD YOU">
When an application is launched from the "not-running" state because a user tapped on a local notification alert, the application has been started by iOS, not by Xcode, thus IT IS NOT RUNNING UNDER THE DEBUGGER. You cannot breakpoint inside it and neither does NSLog() send anything to the Xcode console. Test with a UIAlertController.
</Matrix-Morpheus-Meme>

CTCallCenter - Call Event Handler - in background state

Regarding the Apple documentation there is no way to handle the phone state while the app is suspended:
https://developer.apple.com/documentation/coretelephony/ctcallcenter
"While it is suspended, your application does not receive call events"
Is this also true for the "background" state? (As the background state is not the same with the "suspended" app state regarding the states described in the Apple documentation)
https://web.archive.org/web/20140824215114/https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html
I'm handling the phone state using the following code:
CTCallCenter *callCenter = [[CTCallCenter alloc] init];
callCenter.callEventHandler=^(CTCall* call)
{
//call state
};
I have added a local notifications into the callEventHandler block in order to check if a call events will be received while my app is in background state but is seams that the block is not executed ( my app has a background support and all received events (via TCP) are handled correctly while the app is in background )
All tests that I've done I can't receive any using callEventHandler when the application is in background. But, when the application is in foreground, all nicely work.
The socket works, because iOS handles it for you app and deliver the packtes accordingly. But for that, you need to create a voip socket and add voip to UIBackgroundModes to your App-Info.plist.
You will not be able to monitor phone calls in the background using the callEventHandler...
However, according to this thread in apple dev forums, you can check the currentCalls periodically in the background to determine if calls are in progress.
Here is the code you should use (to check every seconds) :
- (void)viewDidLoad {
[super viewDidLoad];
_timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:#selector(phoneDetection) userInfo:nil repeats:YES];
}
- (void)phoneDetection {
_callCenter = [[CTCallCenter alloc] init]; // Here is the important part : instanciating a call center each time you want to check !
[_callCenter setCallEventHandler:^(CTCall *call) {
NSLog(#"Call detected");
}];
NSLog(#"%#", _callCenter.currentCalls);
}
I know some apps run soundless audio files in the background to prevent from being closed after 10 minutes of inactivity.
Bluetooth, location, and audio can prevent the app from being completely killed.
My app is able to detect incoming vs outgoing calls while in background because the app stays alive with location updates. We have used audio/bluetooth in the past.
Without some method of "keepAlive" the OS will suspend your app until some external stimulus reactivates it (push notification, user launch, etc...)

Check for waiting notifications

With iOS 5 and the notification center you can have waiting, stacked up notifications each with their own data and message. Is there a way when your program is launched regularly (without tapping on the notification) to discover the waiting notifications and more importantly the data associated with them?
The other question associated with this is when the push notifications come in and your app is in the background does application:didReceiveLocalNotification: still get called or does it just go and wait till the app is launched and then you're expected to manually handle it with the launch data in theapplication:didFinishLaunchingWithOptions:
My scenario is that I need to update some core-data models with the data attached to the push notifications so I want those changes reflected no matter how they launch the app.
From my experience, there is no way to find out about notifications other than launching the app directly through them (on iOS 5, that would be right after receiving the notification or from the queued notifications present at the Notification Center).
An alternate strategy would be to use icon badges.
If you badge your app icon when receiving notifications, you could check for that number every time the app is launched and then perform the required actions.
When a notification pops up you can either view it or cancel. If the user has canceled notification, you can check for them the next time they go in the app:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
UILocalNotification *localNotif = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if( localNotif ) {
// Do some stuff
application.applicationIconBadgeNumber = 0; // Reset num of notifications on app icon
}
}
This method gets fired if you receive a notification while you are in that specific app, or you choose to acknowledge a local notification:
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
BOOL inApp = [application applicationState] == UIApplicationStateActive;
if( inApp ) { // they got this in the app
//Do some stuff in the app
}
else {
// They acknowledged the notification out of the app and here they are
// Do some other stuff
}
application.applicationIconBadgeNumber = 0;
}
That gives you good coverage for all scenarios with local notifications which would be:
Notification is received, user cancels. Check later in didFinishLaunchingWithOptions
Notification is acknowledged, the app is not open. Check in didFinishLaunchingWithOptions
Notification is acknowledged, the app is in the background. didReceiveLocalNotification:
Notification is presented while in the app didReceiveLocalNotification: