Showing Local Notifications using Location Manager, While app is in the background - iphone

I am new to iPhone Programming .I have developed one application for checking user entered into a particular region.But i need to check in Background.In background i am checking but the problem is repeating the UILocalNotification alerts .
So how to prevent the repeated UILocalNotifications
- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
NSLog(#"running in background ...");
[self checkRegionEntered];
CurrentlattitudeValue1 =newLocation.coordinate.latitude;
CurrentlongitudeValue1=newLocation.coordinate.longitude;
}
-(void)checkRegionEntered
{
if ([testRegion containsCoordinate:currentCoordinates])
{
[[UIApplication sharedApplication] cancelAllLocalNotifications];
Class cls = NSClassFromString(#"UILocalNotification");
if (cls != nil)
{
UILocalNotification *notif = [[cls alloc] init];
NSDate *now = [NSDate date];
[notif setFireDate:now];
if([Obj.NotesGeo length])
[notif setAlertBody:Obj.NotesGeo];
else
{
[notif setAlertBody:[NSString stringWithFormat:#", you have arrived at %#",Obj.NameGeo]];
}
[notif setAlertAction:#"Launch"];
notif.soundName=[NSString stringWithFormat:#"%#.wav",Obj.Ringtone1];//[NSString stringWithFormat:#"%g",Obj.LatitudeGeo]
NSDictionary *userDict = [NSDictionary dictionaryWithObject:[NSString stringWithFormat:#"%f",Obj.LatitudeGeo] forKey:kRemindMeNotificationDataKey];
notif.userInfo = userDict;
}
}
}

This may help. This logic is designed to ensure that your notification will only fire once, and that the same alert is displayed regardless of whether the app is in the foreground or background when it fires.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Add the view controller's view to the window and display.
[self.window addSubview:viewController.view];
[self.window makeKeyAndVisible];
//detect if app was launched by notification
UILocalNotification *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (notification)
{
//trigger our custom notification handler
[self handleLocalNotification:notification];
}
return YES;
}
- (void)handleLocalNotification:(UILocalNotification *)notification
{
//this is our custom method to handle the in-app notification behaviour
[[[[UIAlertView alloc] initWithTitle:#"You have a notification"
message:#"Yay!"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil] autorelease] show];
}
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
//this standard application delegate method is called under the following circumstances
//1. the app is running in the foreground when the notification fires
//2. the app was running in the background when the notification fired, and the user pressed the action button
//confusingly, if the app was not running when the notification fired, this method won't be called at startup
//automatically and you need to check for the notification key in the launch options instead
if ([UIApplication sharedApplication].applicationState != UIApplicationStateBackground)
{
//this code emulates the same behaviour as when a local notification is received
//when the app is not running (except for playing the sound)
//store notification temporarily
[lastNotification release];
lastNotification = [notification retain];
//get button labels
NSString *actionButton = nil;
NSString *cancelButton = #"Close";
if (notification.hasAction)
{
actionButton = (notification.alertAction)? notification.alertAction: #"View"; //defaults to "View" if nil
cancelButton = #"OK";
}
//show alert
[[[[UIAlertView alloc] initWithTitle:[[NSBundle mainBundle] objectForInfoDictionaryKey:#"CFBundleDisplayName"] //name of application
message:notification.alertBody
delegate:self
cancelButtonTitle:cancelButton
otherButtonTitles:actionButton, nil] autorelease] show];
}
else
{
//trigger our custom notification handler
[self handleLocalNotification:notification];
}
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
if (buttonIndex != alertView.cancelButtonIndex)
{
//trigger our custom notification handler
[self handleLocalNotification:lastNotification];
}
}

Related

iOS Alarm Clock

I have created a simple alarm notification App through which I can get real time, set alarm on or off, and play a single tone audio. But I need to play a sound which should start with a class VOID.
Below is the code:
To get and start alarm notification:
- (void)viewDidLoad {
[super viewDidLoad];
dateTimerPicker.date = [NSDate date];
}
- (void)presentMessage:(NSString *)message {
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:#"Hello!"
message:message
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles: nil];
[alert show];
}
- (void)scheduleLocalNotificationWithDate:(NSDate *)fireDate {
UILocalNotification *notification = [[UILocalNotification alloc]init];
notification.fireDate = fireDate;
notification.alertBody = #"Time to wake up!!";
notification.soundName = #"PhoneOld.mp3";
[self playPause];
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
}
- (IBAction)alarmSetOn:(id)sender{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.timeZone = [NSTimeZone defaultTimeZone];
dateFormatter.timeStyle = NSDateFormatterShortStyle;
dateFormatter.dateStyle = NSDateFormatterShortStyle;
NSString *dateTimeString = [dateFormatter stringFromDate:dateTimerPicker.date];
NSLog(#"Alarm Set: %#", dateTimeString);
[self scheduleLocalNotificationWithDate:dateTimerPicker.date];
[self presentMessage:#"Alarm ON!"];
}
- (IBAction)alarmSetOff:(id)sender {
NSLog(#"Alarm Off");
[[UIApplication sharedApplication] cancelAllLocalNotifications];
[self presentMessage:#"Alarm OFF!"];
}
This is my VOID:
- (void)playPause {
RADAppDelegate *appDelegate = (RADAppDelegate *)[[UIApplication sharedApplication] delegate];
if (appDelegate.radiosound == 0){
[appDelegate.radiosound play];
} else {
[appDelegate.radiosound pause];
}
}
How can I set the alarm to start playing the radiosound if is rated 0, like a:
notification.soundName = [self playPause];
But I know this is a NSString.
You don't need to assign a sound name to scheduled notification, just invoke the playPause method and get the name of sound file from notification, as shown below and just assign it to NSString and set property to it in appDelegate and access it to play that file.
AppDelegate.h
#property (nonatomic,strong) NSString *nsStr_soundFile;
AppDelegate.m
#synthesize nsStr_soundFile;
- (void)application:(UIApplication *)application
didReceiveLocalNotification:(UILocalNotification *)notification {
//Give call to play sound method.
self.nsStr_soundFile=notification.soundName;
VOID *obj=[VOID alloc]init];
[obj playPause];
}
You can make a trick with opting out of iOS multitasking by setting in your app .plist file this key UIApplicationExitsOnSuspend to YES as written here
When an app opts out, it cycles between the not-running, inactive, and
active states and never enters the background or suspended states.
An app that runs in the pre-multitasking compatibility mode keeps
running when the user locks the device while the app is in the
foreground. All the app has to do is wait for the alarm time and
execute its custom code.

startMonitoringSignificantLocationChanges if can terminated my app

i am want to use startMonitoringSignificantLocationChanges in my app,but i have some question,i hope get some help:
for a common app if app enter background,after 10mins ,system can kill the app.if i used startMonitoringSignificantLocationChanges ,when i enter background two hours,my app not terminated,because i click the icon,app will enter the last quit page 。if app is killed,when you click the icon you will first see the default page. so my question is use startMonitoringSignificantLocationChanges my app not killed by system after enter background 10 mins?
if i close mobile,and restart the mobile,when significant location change,my app if can be activate ,i look apple develop document it answer yes.so i test:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
if([CLLocationManager significantLocationChangeMonitoringAvailable]){
[self log:#"sigAvailable=YES"];
}
// Override point for customizatio-n after application launch.
id locationValue = [launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey];
if (locationValue)
{
// create a new manager and start checking for sig changes
[self log:#"didFinishLaunchingWithOptions location key"];
m_locManager = [[CLLocationManager alloc] init];
[self log:#"didFinishLaunchingWithOptions created manager"];
m_locManager.delegate = self;
[self log:#"didFinishLaunchingWithOptions set delegate"];
[m_locManager startMonitoringSignificantLocationChanges];
[self log:#"didFinishLaunchingWithOptions monitoring sig changes"];
// do send local notification
return YES;
}
[self log:#"didFinishLaunchingWithOptions"];
return YES;
}
my question: when restart mobile and local notification,above code is run and log "didFinishLaunchingWithOptions location key" and so on,if i send local notification at the above code, if user will receive?
in ios 6 there is new feature for maps, which stops location updates
It helps to wake app to recieve location updates.link
locationManager.pausesLocationUpdatesAutomatically
Also see all others.
Your app can start on device boot if its VOIP.
see this apple doc
for local notification add to
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// creating local notification
Class cls = NSClassFromString(#"UILocalNotification");
if (cls)
{
UILocalNotification *notification = [launchOptions objectForKey:
UIApplicationLaunchOptionsLocalNotificationKey];
if (notification)
{
NSString *reminderText = [notification.userInfo
objectForKey:kRemindMeNotificationDataKey];
NSLog(#"notification text:%#",reminderText);
// [viewController._msgTextView setText:reminderText];
}
}
application.applicationIconBadgeNumber = 0;
and you can handle them in
- (void)application:(UIApplication *)application
didReceiveLocalNotification:(UILocalNotification *)notification
{
NSLog(#"application:didReceiveLocalNotification:");
}
you can schedule your local notification in
-(void) locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
Class cls = NSClassFromString(#"UILocalNotification");
if (cls != nil)
{
UILocalNotification *notif = [[cls alloc] init];
notif.fireDate = notifyDate;
notif.timeZone = [NSTimeZone defaultTimeZone];
notif.alertBody = AlertMsg;
notif.soundName = UILocalNotificationDefaultSoundName;
notif.applicationIconBadgeNumber = [[UIApplication sharedApplication]applicationIconBadgeNumber]+1;
notif.alertAction = #"Show me";
[[UIApplication sharedApplication] scheduleLocalNotification:notif];
}
}

Execute method if user cancel the UILocaNotification alert in iPhone SDK

I am new to iphone Programming . I am using localNotification in my application.It is giving alert to user and responding to Launch using didReceiveLocalNotification.But my problem is if user close the UILocalNotification in my Application i need to execute database operation .So how can i do that .Is there any approach for that one.
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
NSDate* now = [NSDate date];
[localNotification setFireDate:now];
localNotification.soundName=#"Tink.wav";
[localNotification setAlertAction:#"Launch"];
[localNotification setAlertBody:#"You have entered to Your Place:"];
[localNotification setHasAction: YES];
NSDictionary *userDict = [NSDictionary dictionaryWithObject:#"obj" forKey:kRemindMeNotificationDataKey];
localNotification.userInfo = userDict;
- (void)application:(UIApplication *)app didReceiveLocalNotification:(UILocalNotification *)notif {
NSLog(#"Recieved Notification");
NSString *DateString=[notif.userInfo valueForKey:kRemindMeNotificationDataKey];
if([DateString isEqualToString:#"obj"])
{
[[UIApplication sharedApplication] cancelLocalNotification:notif];
}
NSString *strNotif=[notif.userInfo objectForKey:kRemindMeNotificationDataKey];
if ([strNotif isEqualToString:#"obj"]) {
UIAlertView *alretCheck=[[UIAlertView alloc]initWithTitle:#"notifi Testing in DidRec+" message:strNotif delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alretCheck show];
[alretCheck release];
}
Thanking you in advance.
Now Acc. to my Knowledge we cannot do that what you want. we only have command on the "View" Option of LocalNotification Alert. But if possible u can do one thing onClick on "View" button u can Show an ActionSheet or another alert and on those buttons you can handle all the event you want.

Is it me or xcode... Somethings wrong with my braces and it just causes errors! Please help! iPhone SDK + Urban Push

Help!
I cant find whats wrong. My code is up and mostly running and i needed to incorporate Urban Air push notification and there is something wrong with my code. If there is a better or different way to incorporate this that works without my errors I would appreciate that.
I took this code from a tut of Urban Airmail. I wasnt sure what to inlude and what not to from the sample app.
Now for my code. Ill notate where I get errors They are stray / errors and expected ; b4 :
errors
If you could fix the code that would be awesome!
//
// SuperSlickAppDelegate.m
// SuperSlick
//
// Created by on 8/2/10.
// Copyright __MyCompanyName__ 2010. All rights reserved.
//
#import <SystemConfiguration/SCNetworkReachability.h>
#include <netinet/in.h>
#import "SuperSlickAppDelegate.h"
#import "SuperSlickViewController.h"
#import "Reachability.h"
#implementation SuperSlickAppDelegate
#synthesize window;
#synthesize viewController;
#pragma mark -
#pragma mark Application lifecycle
#define kApplicationKey #"rnftzaemRp2HJMsNjwZvGQ"
#define kApplicationSecret #"X1XdTjdWQIaL72e-gXew5A"
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
Reachability *r = [Reachability reachabilityWithHostName:#"google.com"];
NetworkStatus internetStatus = [r currentReachabilityStatus];
if ((internetStatus != ReachableViaWiFi) && (internetStatus != ReachableViaWWAN))
{
UIAlertView *myAlert = [[UIAlertView alloc] initWithTitle:#"No Internet Connection" message:#"You require an internet connection via WiFi or cellular network to use this! Try the settings app for WiFi Connectivity." delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil];
[myAlert show];
[myAlert release];
}
//Register for notifications
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |UIRemoteNotificationTypeSound |UIRemoteNotificationTypeAlert)];
//ERROR HERE in line above Stray 357
-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)_deviceToken {
//ERROR HERE Wrong type argument to unary minus + stray
// Get a hex string from the device token with no spaces or < >
self.deviceToken = [[[[_deviceToken description] stringByReplacingOccurrencesOfString:#"<"withString:#""]
stringByReplacingOccurrencesOfString:#">" withString:#""]
stringByReplacingOccurrencesOfString: #" " withString: #""];
NSLog(#"Device Token: %#", self.deviceToken);
if ([application enabledRemoteNotificationTypes] == 0) {
NSLog(#"Notifications are disabled for this application. Not registering with Urban Airship");
return;
}
// this is straight out of the UA sample code
NSOperationQueue *queue = [[[NSOperationQueue alloc] init] autorelease];
NSString *UAServer = #"https://go.urbanairship.com";
NSString *urlString = [NSString stringWithFormat:#"%#%#%#/", UAServer, #"/api/device_tokens/", self.deviceToken];
NSURL *url = [NSURL URLWithString: urlString];
ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
request.requestMethod = #"PUT";
// Authenticate to the server
request.username = kApplicationKey;
request.password = kApplicationSecret;
[request setDelegate:self];
[request setDidFinishSelector: #selector(registrationSuccessMethod:)]; // if you want to do something with the token
[request setDidFailSelector: #selector(requestWentWrong:)];
[queue addOperation:request];
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *) error {
NSLog(#"Failed to register with error: %#", error);
}
- (void)requestWentWrong: (ASIHTTPRequest *)request {
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
NSError *_error = [request error];
NSLog(#"ERROR: NSError query result: %#", _error);
UIAlertView *someError = [[UIAlertView alloc] initWithTitle:
#"Network error" message: NSLocalizedString( #"Error registering with notifiction server",
#"Error registering with notifiction server")
delegate: self
cancelButtonTitle: #"OK"
otherButtonTitles: nil];
[someError show];
[someError release];
}
// Add the view controller's view to the window and display.
[window addSubview:viewController.view];
[window makeKeyAndVisible];
return YES;
}
}
- (void)applicationWillResignActive:(UIApplication *)application {
/*
Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
*/
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
/*
Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
If your application supports background execution, called instead of applicationWillTerminate: when the user quits.
*/
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
/*
Called as part of transition from the background to the inactive state: here you can undo many of the changes made on entering the background.
*/
}
- (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.
*/
}
- (void)applicationWillTerminate:(UIApplication *)application {
/*
Called when the application is about to terminate.
See also applicationDidEnterBackground:.
*/
}
#pragma mark -
#pragma mark Memory management
- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application {
/*
Free up as much memory as possible by purging cached data objects that can be recreated (or reloaded from disk) later.
*/
}
- (void)dealloc {
[viewController release];
[window release];
[super dealloc];
}
#end
New Code that has troubles:
//Register for notifications
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |UIRemoteNotificationTypeSound |UIRemoteNotificationTypeAlert)];
;}}
-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)_deviceToken {
//ERROR HERE Wrong type argument to unary minus and semi colon b4
Doesn't look like you ever ended your application:didFinishLaunchingWithOptions: method - you should have an end brace after this line:
[[UIApplication sharedApplication] registerForRemoteNotificationTypes...
So it should look like this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge |UIRemoteNotificationTypeSound |UIRemoteNotificationTypeAlert)];
//ERROR HERE in line above Stray 357
}
-(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)_deviceToken {
...
}
That should do it.
For your second code block - without seeing the surrounding code it's difficult to see what you're trying to do...you likely shouldn't have:
;}}
It should probably just be:
}
If you are looking for unbalanced parentheses, then this is probably the part that is giving you troubles:
[window addSubview:viewController.view];
[window makeKeyAndVisible];
return YES;
}
}

local notification "didReceiveLocalNotification" calls twice

I am handling local notifications using:
- (void)application:(UIApplication *)app didReceiveLocalNotification:(UILocalNotification *)notif
And to schedule a local notification:
- (void)scheduleNotificationWithInterval:(int)minutesBefore {
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
if (localNotif == nil)
return;
NSDate *fireDate = [NSDate date];
localNotif.fireDate = [fireDate dateByAddingTimeInterval:minutesBefore*60];
localNotif.timeZone = [NSTimeZone defaultTimeZone];
localNotif.repeatInterval = kCFCalendarUnitMinute;
localNotif.alertBody = [NSString stringWithFormat:NSLocalizedString(#"LocalEvent notification in %i minutes.", nil),minutesBefore];
localNotif.alertAction = NSLocalizedString(#"View Details", nil);
localNotif.applicationIconBadgeNumber = 1;
NSDictionary *infoDict = [NSDictionary dictionaryWithObjectsAndKeys:#"This is dict, you can pass info for your notification",#"info",nil];
localNotif.userInfo = infoDict;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
[localNotif release];
NSLog(#"Event scheduled");
}
When I receive a notification, didReceiveLocalNotification: is called twice.
Am I doing something wrong?
Please help.
Thanks.
I think there is a known bug in the simulator, that fires the delegate notification method twice. It should not happen on the device, tethered to XCode or not.
i was also facing the same problem and the solution which i find is that write this code in didReceiveLocalNotification
if (state == UIApplicationStateActive) {
NSLog(#"UIApplicationStateActive");
}
else if(state == UIApplicationStateInactive){
NSLog(#"UIApplicationStateInActive");
}
here in these condition i just write the code which i want my application to do on notification , in Active mode and in inactive mode
I suspect that the notification is being retriggered as long as its in the same second still. I fixed it by setting the fireDate to nil in the handler:
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:notification.alertAction message:notification.alertBody delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertView show];
notification.fireDate = nil;
}
I had the same issued. It was caused by calling 'registerUserNotificationSettings' twice in the AppDelegate's 'didFinishLaunchingWithOptions.' However, simply removing the duplicate call did not fix the problem yet. I had to delete the app and then rebuild. Only then did the double local notification issue get fixed.