I'm using a Beacon device for testing. The scenario is as follows.
I'm throwing a local notifications when receiver enters the location which is based on latitude & longitude range which i have set manually. This works fine and i'm clearing this notification on didFinishLaunchingWithOptions. When I enter to the next closest region i'm getting the notification and on clicking it I can able to present a view. But when i come out of the app the local notifications are not getting cleared. What may be the problem?
I'm using two different methods for two different regions.
1st one is
-(void) didEnterLocation:(SLMLocation*)location
{
// throwing a local notification
}
the above method's notification is getting cleared in
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[[UIApplication sharedApplication] cancelAllLocalNotifications];
}
the second method is as follows: this is for 2nd region
- (void) didEnterNewClosestRegion :(SLMBLERegion*) region
{
// throwing local notifications here & notifications are visible
}
Now in the second method only I can't able to clear the local notification. Your help is highly appreciated.
try this may be help full ..
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
[[UIApplication sharedApplication] cancelAllLocalNotifications];
}
Thanks
This is because didFinishLaunchingWithOptions method is only called one in app life time, there is a possibility that it is already running in background so the notifications will not be cleared. I would suggest you to move cancelling code to applicationDidBecomeActive.
cancelAllLocalNotifications, cancels the delivery of all scheduled local notifications, it doesn't clear already presented notifications from lock-screen or notification-center.
https://developer.apple.com/library/ios/documentation/uikit/reference/UIApplication_Class/Reference/Reference.html#//apple_ref/occ/instm/UIApplication/cancelAllLocalNotifications
Related
In my iOS application i want to make an api call for every 4 hours.
As of my research i found that it can be achieved by background task or Local notification or Push Notification.
As of my knowledge, By Notifications (Either Local or Push both) user have to interact with application.
I want to make an api call without user interaction, even app is in background or foreground or active.
I didn't get exact sample code for background fetch which works with intervals.
Some one please guide me in this issue.
Thank you in Advance.
You can set the interval here or specified a minimum fetch interval (The smallest fetch interval supported by the system) like this example:
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];
return YES;
}
For 4 hours:
NSTimeInterval fourHours = 14400;
[[UIApplication sharedApplication] setMinimumBackgroundFetchInterval:fourHours];
I am trying to detect if my app was launched from push, and there are tons of threads and answers. They are all wrong in my case, and lead me to writing incorrect behavior. They all tell to write roughly this:
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
BOOL wasLaunchedFromPush = NO;
if (application.applicationState == UIApplicationStateInactive) {
wasLaunchedFromPush = YES;
}
...
}
Or this:
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
BOOL wasLaunchedFromPush = NO;
if (application.applicationState == UIApplicationStateInactive || application.applicationState == UIApplicationStateBackground) {
wasLaunchedFromPush = YES;
}
...
}
When I try this, my app thinks that it was started from a notification when I'm on a phone call, the app is in the background, pretty much always when the app is running but not directly active. When my users return to the app, app acts like they've tapped the notification and opened it, whereas the user hasn't interacted with it at all. I don't know why people accepted that as a correct answer in many questions.
How can I simply check if my app is launched from a notification or not, also regardless of the previous state of the app (running in the background or just launched)?
There is no simple way which is going to tell you that its open from pushNotificaiton specially when app is in active or in background. You have to do some work around,
UIApplicationStateInactive The app is running in the foreground but is
not receiving events. This might happen as a result of an interruption
or because the app is transitioning to or from the background
This is best candidate for the phone call interruption,
You can also add some other work around to check if app ever entered in background or not, if yes then after that if didReceiveRemoteNotification method get called its means its from push notification.
If you only want to know when your app was launched from a remote notification, you should check for this in - application:didFinishLaunchingWithOptions: or - application:willFinishLaunchingWithOptions:. You can check for the presence of UIApplicationLaunchOptionsRemoteNotificationKey in the launchOptions dictionary.
didReceiveRemoteNotification is call when your app is running and a remote notification is received. It is called regardless of any user interaction this is because if the app is running, there will not be a notification (pop up) for the user to interact with.
Checking against UIApplicationStateBackground is definitely wrong. If your push notifications are marked with content-available: 1 then your app is going to be called in that state so that you can perform your content download. This will happen without any user interaction.
The best I know of is using the check against UIApplicationStateInactive alone (i.e. your first code example).
As you say, this doesn't work if the notification arrives while your app has been interrupted by a phone call. That's an interesting problem. You could maybe keep track of call state using CTCallCenter but I've not done that and I don't know if you need VOIP permission to make it work.
I am developing an app where I need to alert the user using UILocalNotification for a specific time interval
The problem is that I place the code in applicationDidEnterBackground..
So evrytime the user close the app. a New notification is created, resulting in multiple notifications created. How do I go about this problem? Thank you
- (void)applicationDidEnterBackground:(UIApplication *)application
{
}
I'm developing a Calendar/Alarm app for iOS which is synchronising with a web server. When an activity is added on the server, a push notification is sent out so that the iOS client can fetch the new data and, if needed, update and schedule the time for next alarm (local notification).
But this only works when the app is open on client side. I would like the client to receive the push notifications and if needed, re-schedule the time for next alarm in background.
Is this impossible on iOS?
You can use Background Fetch for this, where the OS will "wake up" your app periodically to perform data fetching in the background.
First, enable the background fetch capability for your app. In XCode 6, view your project, then go to the Capabilities tab, turn on Background Modes, and check Background Fetch.
Then you'll have to implement some codes in the App Delegate:
In application:didFinishLaunchingWithOptions:, add:
[application setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];
The above sets how often you wish the system to "wake up" your app for background processes ideally. Note that the final frequency is determined by an algorithm in the iOS, so it may not always be this often.
-(void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler{
//fetch code here
completionHandler(UIBackgroundFetchResultNewData);
}
The above is the actual overridden function that is called during this period of background process. Remember to call the completionHandler - failing to do so might reduce the chance of your app being run in the background next time (or so says the docs). The enums you may pass to the completionHandler are UIBackgroundFetchResultNewData, UIBackgroundFetchResultNoData, UIBackgroundFetchResultFailed. Use one of these depending on the result of your fetch.
// use this methods in Appdeleagte
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
[self showAlarm:notification.alertBody];
application.applicationIconBadgeNumber = 1;
application.applicationIconBadgeNumber = notification.applicationIconBadgeNumber-1;
}
// call this in appdelagete
-(void)makeNotificationRequest:(UILocalNotification *)notification1
{
[self showAlarm:notification1.alertBody];
}
// call this mathods in appdelagte
- (void)showAlarm:(NSString *)text {
**strong text**
// set notification and call this notification methods your another view .....
[[NSNotificationCenter defaultCenter] postNotificationName:#"uniqueNotificationName" object:self]; //leak
}
I have the following issue: "My app receive some remote notifications from an own server just to show to the user some practical information. I am not using a icon badge, because I don't need it. If the application user touch the remote notification from the iOS Notification Center my application can catch it without any problem, I receive the options from application:didFinishLaunchingWithOptions: or, if the application is open I catch the remote notification with application:didReceiveRemoteNotification: selector. But, now I want to remove these notifications from iOS Notification Center because It is just a message and I have been looking for the answer in another posts and I've tried these solutions in my app and they don't work"
Some solutions were the next:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
[application cancelAllLocalNotifications];
application.applicationIconBadgeNumber = 0;
...
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
...
if (launchOptions) {
[application cancelAllLocalNotifications];
application.applicationIconBadgeNumber = 0;
}
...
}
And the remote notification still in the iOS Notification Center, how can I remove from that place without any tricky code or is an iOS SDK issue? I don't think that an issue was possible because Tweetbot app remove its remote notifications from iOS Notification Center after you enter to the app.
Regards!
With introduction of UNUserNotificationCenter for iOS 10 and above, it is now possible to remove few or all remote notifications of your app.
UNUserNotificationCenter documentation
With a shared singleton instance of this class, it is possible to manage delivered remote notifications on the device. Specifically, the following methods can be used:
func removeDeliveredNotifications(withIdentifiers: [String]) if you want to remove specific notification of your app, OR func removeAllDeliveredNotifications() to remove all notifications of your app.
First of all make sure you haven't set badge notification to be off in the control panel (I noticed that if the badge has a number to begin with, then badging is turned off in the control panel, it cannot be set to 0).
If its not turned off then in addition to setting applicationIconBadgeNumber to 0, also try canceling all local notifications (even if you haven't queued any, if you have first get a list of them, then cancel them, then register them back again). Yes clearing local notifications can have an effect on being able to clear the badge number for remote notifications.