UIlocalNotification did now appear without starting background task - iphone

I have a voip application.
I am using UILocalNotification in my application to alert notification for incoming call when application in background.
When application is in background, after getting an incoming call following function is called.
-(void)showLocalNotification:(NSNotification *)notification {
NSDictionary *dic = notification.userInfo;
NSString *msg = [dic objectForKey:#"msg"];
NSString *sound = [dic objectForKey:#"sound"];
[[UIApplication sharedApplication] cancelAllLocalNotifications];
UILocalNotification *_localNotification = [[UILocalNotification alloc]init];
//setting the fire dat of the local notification
_localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:1];
//setting the time zone
_localNotification.timeZone = [NSTimeZone defaultTimeZone];
//setting the message to display
_localNotification.alertBody = msg;
//default notification sound
if ([sound length]==0) {
_localNotification.soundName = UILocalNotificationDefaultSoundName;
} else {
_localNotification.alertAction = NSLocalizedString(#"Receive", nil);
_localNotification.soundName = #"myringtone.aif";
}
//displaying the badge number
_localNotification.applicationIconBadgeNumber = [[UIApplication sharedApplication]applicationIconBadgeNumber]+1;
//schedule a notification at its specified time with the help of the app delegate
[[UIApplication sharedApplication]scheduleLocalNotification:_localNotification];
}
This function set a scheduleLocal notification to show an alert with two buttons Cancel and Receive which fires after a second.
Now the problem is:
This local notification appears to user only when a background task started as following
- (void)applicationDidEnterBackground:(UIApplication *)application
{
UIApplication* app = [UIApplication sharedApplication];
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
}
But after 10 minutes background task stops. Then local notification does not appear to user though it fires (A log prints after firing)
I did modify the applicationDidEnterBackground function as following to restart background task for long running. But unable.
- (void)applicationDidEnterBackground:(UIApplication *)application
{
expirationHandler = ^{
[app endBackgroundTask:self.bgTask];
self.bgTask = UIBackgroundTaskInvalid;
self.bgTask = [app beginBackgroundTaskWithExpirationHandler:expirationHandler];
}
self.bgTask = [app beginBackgroundTaskWithExpirationHandler:expirationHandler];
}
Now the questions are:
Is there any way which will fire local notification and appear to user when application is in background?
If background task is mandatory, how could be it long run to show local notification to appear user after 10 minutes?
I am using iPhone 3gs, iPhone 4 and iPhone 5.

Try This :
- (void)applicationDidEnterBackground:(UIApplication *)application
{
__block UIBackgroundTaskIdentifier bgTask ;
UIApplication *app = [UIApplication sharedApplication];
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
pollingTimer2 = [NSTimer scheduledTimerWithTimeInterval:4.0f target:self selector:#selector(process) userInfo:nil repeats:YES];
}
-(void) process
{
[self didLocalNotification];
}
-(void)didLocalNotification
{
[[UIApplication sharedApplication]cancelAllLocalNotifications];
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
if (localNotification == nil)
{
return;
}
NSLog(#"calling didLocalNotification");
localNotification.applicationIconBadgeNumber =0;
localNotification.alertBody =#"Message!";
localNotification.soundName = UILocalNotificationDefaultSoundName;
localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:0];
localNotification.timeZone = [NSTimeZone defaultTimeZone];
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
}

Related

iOS accelerometer in the background (infinite)

I would like my app to monitor my accelerometer for an infinite time (even in the background). When it reaches a certain amount, I would like to deliver a local notification. This is exactly the same functionality as the 'Sleep Cycle' app has.
But how did they do this? When I use the beginBackgroundTaskWithExpirationHandler function, it isn't working anymore after 10 minutes. Adding UIBackgroundModes doesn't help at all.
UIApplication *app = [UIApplication sharedApplication];
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
_motionManager = [[CMMotionManager alloc] init];
_motionManager.accelerometerUpdateInterval = 1;
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[_motionManager startAccelerometerUpdatesToQueue:queue withHandler:^(CMAccelerometerData *accelerometerData, NSError *error)
{
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(#"%#",accelerometerData);
if(accelerometerData.acceleration.x > 0.5){
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
if (localNotif == nil)
return;
localNotif.fireDate = [NSDate date];
localNotif.timeZone = [NSTimeZone defaultTimeZone];
localNotif.alertBody = #"Wake up!";
localNotif.alertAction = #"wake";
localNotif.soundName = UILocalNotificationDefaultSoundName;
localNotif.applicationIconBadgeNumber = 4;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}
});
}];
To run your app infinitely in background, you need to provide the UIBackgroundModes value in Info.plist file.
https://developer.apple.com/library/ios/documentation/iphone/conceptual/iphoneosprogrammingguide/ManagingYourApplicationsFlow/ManagingYourApplicationsFlow.html#//apple_ref/doc/uid/TP40007072-CH4-SW20

Repeat alarm at particular time interval

Issue is, i put a date picker programmatically. In date picker i just used to display time from 1mins to 23 hours. User is supposed to set the time in the picker, and set up the notification.
Now,i get notification in background but only one time.I have to repeat time until timer will not stop.
I found too many links and source but not able to solve this issue
My Code:
In Appdelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
application.applicationIconBadgeNumber = 0;
//------ Handle launching from a notification-------
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
self.localNotification =[launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (self.localNotification)
{
application.applicationIconBadgeNumber = self.localNotification.applicationIconBadgeNumber-1;
NSLog(#"badge number: %d", application.applicationIconBadgeNumber);
[self playSoundWithNotification:self.localNotification];
}
else
{
[[UIApplication sharedApplication]cancelAllLocalNotifications];
}
}
didenterinbackground:
- (void)applicationDidEnterBackground:(UIApplication *)application
{
NSLog(#"Application entered background state.");
NSAssert(self->bgTask == UIBackgroundTaskInvalid, nil);
bgTask = [application beginBackgroundTaskWithExpirationHandler: ^{
dispatch_async(dispatch_get_main_queue(), ^{
[application endBackgroundTask:self->bgTask];
self->bgTask = UIBackgroundTaskInvalid;
});
}];
dispatch_async(dispatch_get_main_queue(), ^{
while ([application backgroundTimeRemaining] > 1.0)
{
NSString *str_friend = #"Hello,";
if (str_friend)
{
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
if (localNotif)
{
localNotif.alertBody = [NSString stringWithFormat:
NSLocalizedString(#"%# has a message for you.", nil), str_friend];
localNotif.alertAction = NSLocalizedString(#"Read Msg", nil);
localNotif.soundName = #"alarmsound.caf";
//localNotif.soundName =[NSString stringWithFormat:#"%#.mp3",str_Alarm];
localNotif.applicationIconBadgeNumber = 1;
[application presentLocalNotificationNow:localNotif];
NSLog(#"sound: %#, alertAction: %#, alerBody: %#",localNotif.soundName, localNotif.alertAction, localNotif.alertBody);
str_friend = nil;
break;
}
}
}
[application endBackgroundTask:self->bgTask];
self->bgTask = UIBackgroundTaskInvalid;
});
}
-
(void)playSoundWithNotification:(UILocalNotification *)notification
{
notification.soundName=[NSString stringWithFormat:#"%#.mp3",str_Alarm];
NSLog(#"soundname: %#",notification.soundName);
}
- (void)application:(UIApplication *)app didReceiveLocalNotification:(UILocalNotification *)notif
{
testDate=notif.fireDate;
NSLog(#"DATE IS: %#, %#",testDate, notif.fireDate);
// Handle the notificaton when the app is running
NSLog(#"Recieved Notification %#",notif);
[self playSoundWithNotification:notif];
[self _showAlert:[NSString stringWithFormat:#"%#",str_Motivation] withTitle:#"Daily Achiever"];
}
- (void) _showAlert:(NSString*)pushmessage withTitle:(NSString*)title
{
UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:title message:pushmessage delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertView show];
if (alertView)
{
}
}
in myviewcontroller:
-(void)insert:(NSDate *)fire
{
appDelegate=(AppDelegate *)[[UIApplication sharedApplication] delegate];
appDelegate.localNotification = [[UILocalNotification alloc] init];
NSLog(#"localNotification %#", appDelegate.localNotification);
if (appDelegate.localNotification == nil)
return;
appDelegate.localNotification.fireDate = fire;
appDelegate.localNotification.timeZone = [NSTimeZone defaultTimeZone];
appDelegate.localNotification.alertBody = appDelegate.str_Motivation;
appDelegate.localNotification.alertAction = #"View";
appDelegate.localNotification.soundName = [NSString stringWithFormat:#"%#.mp3",appDelegate.str_Alarm];
appDelegate.localNotification.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber]+1;
NSLog(#"localNotification.alertBody %#", appDelegate.localNotification.alertBody);
NSLog(#"localNotification.soundName %#",appDelegate.localNotification.soundName);
[[UIApplication sharedApplication] scheduleLocalNotification:appDelegate.localNotification];
}
Please Help.
- (void)applicationDidEnterBackground:(UIApplication *)application
{
......
......
if (localNotif)
{
localNotif.alertBody = [NSString stringWithFormat:
NSLocalizedString(#"%# has a message for you.", nil), str_friend];
localNotif.alertAction = NSLocalizedString(#"Read Msg", nil);
localNotif.soundName = #"alarmsound.caf";
localNotif.applicationIconBadgeNumber = 1;
[localNotif setRepeatInterval:NSMinuteCalendarUnit];
[application presentLocalNotificationNow:localNotif];
str_friend = nil;
break;
}
}
I got solution.

Local Notification on ViewController

I have the following code in ViewController.m:
-(void) checker {
UILocalNotification *notification = [[UILocalNotification alloc] init];
[notification setAlertBody: #"Im your local notification"];
[notification setFireDate: [NSDate dateWithTimeIntervalSinceNow: 1]];
[notification setTimeZone: [NSTimeZone defaultTimeZone]];
[UIApplication setScheduledLocalNotifications: [NSArray arrayWithObject: notification]];
}
The last line produces a warning:
Class method '+setScheduledLocalNotifications' not found (return type defaults to id)
and it gives error while processing. How can I instantiate the notification? As I said I am new, if you can provide a complete answer it will be greatly appreciated.
Edit: I have a timer that repeats itself every 60 seconds and calls a function that puts a notification.
timer = [NSTimer scheduledTimerWithTimeInterval:60 target:self selector:#selector(checker) userInfo:nil repeats:YES];
/* ... */
-(void)checker {
NSLog(#"Notification routine");
UIApplication* app = [UIApplication sharedApplication];
NSArray *oldNotifications = [app scheduledLocalNotifications];
// Clear out the old notification before scheduling a new one.(if needed)
if ([oldNotifications count] > 0)
[app cancelAllLocalNotifications];
// Create a new notification.
UILocalNotification* alarm = [[[UILocalNotification alloc] init] autorelease];
if (alarm) {
alarm.fireDate = [NSDate dateWithTimeIntervalSinceNow:10];
alarm.timeZone = [NSTimeZone defaultTimeZone];
alarm.repeatInterval = 0;
alarm.alertBody = #"Msg to show";
[app scheduleLocalNotification:alarm];
}
}
I can see the log only firing once a minute, but the oldNotifications count does not increase.
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
the '+' in the error message means it is trying to call a class method rather than an instance method. The [UIApplication sharedApplication] call will return the singleton instance of the application object that allows you to call that method as an instance method.
Also you should read the documentation for UIApplication. You just need to call scheduleLocalNotification: with the notification object to get it scheduled. This will allow you to release the memory to the object, because the schedule method will copy the object.
This is how I do it,
UIApplication* app = [UIApplication sharedApplication];
NSArray *oldNotifications = [app scheduledLocalNotifications];
// Clear out the old notification before scheduling a new one.(if needed)
if ([oldNotifications count] > 0)
[app cancelAllLocalNotifications];
// Create a new notification.
UILocalNotification* alarm = [[[UILocalNotification alloc] init] autorelease];
if (alarm)
{
alarm.fireDate = [NSDate dateWithTimeIntervalSinceNow:60*60];//afterone hour
alarm.timeZone = [NSTimeZone defaultTimeZone];
alarm.repeatInterval = 0;
alarm.soundName = #"alarmsound.caf";
alarm.alertBody = #"Msg to show";
[app scheduleLocalNotification:alarm];
}
update:
- (void)scheduleAlarmForDate:(NSDate*)theDate andBody:(NSString*)Body
{
UIApplication* app = [UIApplication sharedApplication];
NSArray *oldNotifications = [app scheduledLocalNotifications];
// Clear out the old notification before scheduling a new one.
if ([oldNotifications count] > 0)
[app cancelAllLocalNotifications];
// Create a new notification.
UILocalNotification* alarm = [[UILocalNotification alloc] init];//Using ARC no autorelease
if (alarm)
{
alarm.fireDate = theDate;
alarm.timeZone = [NSTimeZone defaultTimeZone];
alarm.repeatInterval = 0;
alarm.soundName = #"alarmsound.caf";
alarm.alertBody = Body;
[app scheduleLocalNotification:alarm];
}
}
now if I call this method twice,
NSDate *fireDate1 = [NSDate dateWithTimeIntervalSinceNow:4.0];
[self scheduleAlarmForDate:fireDate1 andBody:#"My alertBody 1"];
NSDate *fireDate2 = [NSDate dateWithTimeIntervalSinceNow:6.0];
[self scheduleAlarmForDate:fireDate2 andBody:#"My alertBody 2"];
the first alarm will be canceled,,

Appdelegate function 'didreceivelocalnotification' is called immediately after the notification is created

I'm using UILocalNotifications in iPhone to create an alarm. Alarm is scheduled when I click a UIButton. My issue is that – application:didReceiveLocalNotification: is called when I click this button, that is when I create a local notification. But , – application:didReceiveLocalNotification: should be called only when the notification time is reached. I checked it on both simulator and device and got the same results. Can anyone help me with this...thanks in advance.
-(void)createalarm:(NSString *)datend_time:(NSString *)message//creating alarm
{
NSLog(#"created!!!!!!!!!!!!!");
NSString *datestr = datend_time;
NSString *textstr = message;
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
[formatter setDateFormat:#"MM/dd/yyyy hh:mm a"];
NSDate *alerttime = [formatter dateFromString:datestr];
UIApplication * app = [UIApplication sharedApplication];
UILocalNotification *notification = [[UILocalNotification alloc] init];
if (notification)
{
notification.fireDate = alerttime;
//notification.timeZone = [NSTimeZone defaultTimeZone];
notification.repeatInterval = 0;
notification.alertBody = textstr;
notification.soundName = UILocalNotificationDefaultSoundName;
[app scheduleLocalNotification:notification];
[app presentLocalNotificationNow:notification];
}
}
-(void)application:(UIApplication *)application didReceiveLocalNotification: (UILocalNotification *)notification
{
NSLOG(#"delegate called")
}
It is because you call
[app presentLocalNotificationNow:notification];
So it shows the notification right after you created it. Remove this line of code.
[app scheduleLocalNotification:notification]; will work just fine and will shot the notification at fireDate.
Here is an example of NSLocalnotification:
-(void) scheduleNotificationForDate: (NSDate*)date {
/* Here we cancel all previously scheduled notifications */
[[UIApplication sharedApplication] cancelAllLocalNotifications];
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = date;
NSLog(#"Notification will be shown on: %#",localNotification.fireDate);
localNotification.timeZone = [NSTimeZone defaultTimeZone];
localNotification.alertBody = [NSString stringWithFormat:
#"Your notification message"];
localNotification.alertAction = NSLocalizedString(#"View details", nil);
/* Here we set notification sound and badge on the app's icon "-1"
means that number indicator on the badge will be decreased by one
- so there will be no badge on the icon */
localNotification.soundName = UILocalNotificationDefaultSoundName;
localNotification.applicationIconBadgeNumber = -1;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
}
Make sure that the date you are setting is not in the past!

application run in background

I want to develop app that get current location in background mode of app , and generate according to location particular event ,
So , how can I make app that go in to background and get continues location.
Apple has written a demo app doing exactly what is asked: Breadcrumb
- (CLLocationManager *)locationManager
{
if (locationManager != nil)
return locationManager;
locationManager = [[CLLocationManager alloc] init];
//locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters;
locationManager.delegate = self;
return locationManager;
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
UIApplication* app = [UIApplication sharedApplication];
// Request permission to run in the background. Provide an
// expiration handler in case the task runs long.
NSAssert(bgTask == UIBackgroundTaskInvalid, nil);
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
// Synchronize the cleanup call on the main thread in case
// the task actually finishes at around the same time.
dispatch_async(dispatch_get_main_queue(), ^{
if (bgTask != UIBackgroundTaskInvalid)
{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
});
}];
// Start the long-running task and return immediately.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Do the work associated with the task.
// Synchronize the cleanup call on the main thread in case
// the expiration handler is fired at the same time.
dispatch_async(dispatch_get_main_queue(), ^{
if (bgTask != UIBackgroundTaskInvalid)
{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}
});
});
}
- (void) locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation`
{
NSLog(#"location changed");
UIApplication* app = [UIApplication sharedApplication];
NSArray* oldNotifications = [app scheduledLocalNotifications];
// Clear out the old notification before scheduling a new one.
if ([oldNotifications count] > 0)
[app cancelAllLocalNotifications];
// Create a new notification.
UILocalNotification* alarm = [[[UILocalNotification alloc] init] autorelease];
if (alarm)
{
alarm.timeZone = [NSTimeZone defaultTimeZone];
alarm.repeatInterval = 0;
alarm.soundName = #"b.wav";
alarm.alertBody = #"Location changed!";
[app scheduleLocalNotification:alarm];
}
}