UILocalNotification triggering multiple times - ios

I am using UILocalNotification and here's my code
-(void)notificationScheduler
{
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
// localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:7];
localNotification.alertBody = #"NPS message";
localNotification.timeZone = [NSTimeZone defaultTimeZone];
localNotification.soundName = UILocalNotificationDefaultSoundName;
localNotification.repeatInterval = 0;
//Setting badge
[UIApplication sharedApplication].applicationIconBadgeNumber += 1;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
}
I am calling this method in a button click action. Notification is delivering to phone continuously.
I tried this code to stop the notification
- (void)application:(UIApplication *)application
didReceiveLocalNotification:(UILocalNotification *)notification{
NSLog(#"didReceiveLocalNotification");
[application cancelLocalNotification:notification];
}
but didReceiveLocalNotification method is not getting called.
Button action code
- (IBAction)btnSendClicked:(id)sender
{
[self notificationScheduler ];
// saves in dB of sttarter and then reloads tableview to display the message.
if (![self.txtMessage.text isEqualToString:#""])
{
// publish message
[objSttarter SttarterClassPublishTopic:strTopicIdToCompare strData:self.txtMessage.text];
NSMutableDictionary *dctMessage = [[NSMutableDictionary alloc]init];
[dctMessage setValue:#"message" forKey:#"type"];
[dctMessage setValue:#"" forKey:#"timestamp"];
[dctMessage setValue:#"You" forKey:#"from"];
[dctMessage setValue:#"none" forKey:#"file_type"];
[dctMessage setValue:#"" forKey:#"file_url"];
[dctMessage setValue:#"False" forKey:#"sender"];// false = You sent a msg back.
NSMutableDictionary *dctPayload =[[NSMutableDictionary alloc]init];
[dctPayload setValue:#"" forKey:#"title"];
[dctPayload setValue:strTopicIdToCompare forKey:#"topic"];//*
[dctPayload setValue:self.txtMessage.text forKey:#"message"];//*
[dctMessage setValue:dctPayload forKey:#"payload"];
[[DatabaseHandler sharedDatabaseHandler] insertDataToMessages:dctMessage];
// NSIndexPath *path1 = [NSIndexPath indexPathForRow:arrmsg.count inSection:0];
// NSArray *indexArray = [NSArray arrayWithObjects:path1,nil];
// [arrmsg addObject:self.txtMessage.text];
// [self.tableviewChat beginUpdates];
// [self.tableviewChat insertRowsAtIndexPaths:indexArray withRowAnimation:UITableViewRowAnimationNone];
// [self.tableviewChat endUpdates];
// [self.view endEditing:YES];
// self.txtMessage.text=#"";
self.txtMessage.text =#"";
}
}

I changed appdelegate didReceiveLocalNotification code to this and it worked.
- (void)application:(UIApplication *)application
didReceiveLocalNotification:(UILocalNotification *)notification
{
NSLog(#"didReceiveLocalNotification");
[application cancelLocalNotification:notification];
[[UIApplication sharedApplication] cancelAllLocalNotifications];
}

Related

Objective C IOS - SingalR 2 don't connect in background fetch

I have created an app with SignalR Ver 2. SignalR works when the app is in the foreground, but when the app is backgrounded SignalR is not connecting! There is one thing I don't understand; when I test the app in the simulator using objective c it works and connects but it don't work when I send the app to my phone!
-(void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
if ([[NSUserDefaults standardUserDefaults]stringForKey:#"UserName"]) {
//[self performBackgroundTask];
}
completionHandler (UIBackgroundFetchResultNewData);
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
if ([UIApplication instancesRespondToSelector:#selector(registerUserNotificationSettings:)]){
[application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound categories:nil]];
}
// Override point for customization after application launch.
return YES;
}
- (void)performBackgroundTask
{
NSString *buf = [[NSUserDefaults standardUserDefaults]stringForKey:#"UserName"];
connection = [SRHubConnection connectionWithURL:#"http://yoursite.com/"];
myHub = [connection createHubProxy:#"MobileNotification"];
NSLog(#"%#",myHub);
connection.started = ^{
[myHub invoke:#"init" withArgs:[NSArray arrayWithObjects: buf, nil]];
};
connection.reconnected =^{
[myHub invoke:#"init" withArgs:[NSArray arrayWithObjects: buf, nil]];
};
[myHub on:#"agentMessage" perform:self selector:#selector(notificationReceived::)];
[connection setDelegate:self];
[connection start];
[UIApplication sharedApplication].applicationIconBadgeNumber = 0;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
});
}
- (void)notificationReceived:(NSString*)RecipientId:(id)message
{
NSDictionary *json = message;
int RId = [[json objectForKey:#"RecipientId"] integerValue];
[json objectForKey:#"Username"];
NSString *body = [json objectForKey:#"Body"];
NSString *time = [json objectForKey:#"CreationTime"];
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = [NSDate date];
localNotification.alertBody = [NSString stringWithFormat:#"%# - %#",body,time];
localNotification.timeZone = [NSTimeZone defaultTimeZone];
static int i=1;
[UIApplication sharedApplication].applicationIconBadgeNumber = i++;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
[myHub invoke:#"UpdateStatus" withArgs:[NSArray arrayWithObjects:[NSNumber numberWithInteger:RId],#"Delivered", nil]];
}
Please tell me what solution is better for background service and SignalR?
Best Regard
Mani

using UILocalNotification with core location

I have this code which send user notifications every time the distance between an event that occur in a local JSON file and his current location is < 100 meter asking him whether he is at that event or not , when he presses on yes then that event will be marked as attended. the thing is I tried to do that by using some code i found online but I'm not sure if it is the right way to do it, anyway i tested it on my iPhone and what happened is when i arrived to an event location it kept sending unstoppable notifications and when i try to press yes or no nothing actually happen it keeps sending these notifications. Can anyone plz explain for me what is going wrong, I'm not very familiar with Xcode and objective-C language. The code i used is shown below.
in AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// load Core Data
NSManagedObjectContext *context = [self managedObjectContext];
if (!context) {
NSLog(#"No NSManagedObjectContext generated");
}
NSLog(#"DelegateApp Managed Object Context = %#", context);
[[DataManager sharedInstance] setManagedObjectContext:context];
[[DataManager sharedInstance] initDataBase];
return YES;
UILocalNotification *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (notification) {
[self showAlarm:notification.alertBody];
NSLog(#"AppDelegate didFinishLaunchingWithOptions");
application.applicationIconBadgeNumber = 0;
}
[self.window makeKeyAndVisible];
return YES;
}
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
[self showAlarm:notification.alertBody];
application.applicationIconBadgeNumber = 0;
NSLog(#"AppDelegate didReceiveLocalNotification %#", notification.userInfo);
}
- (void)showAlarm:(NSString *)text {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"SPOT IT"
message:text delegate:self
cancelButtonTitle:#"YES"
otherButtonTitles:#"NO",nil];
[alertView show];
}
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
NSString *title = [alertView buttonTitleAtIndex:buttonIndex];
if([title isEqualToString:#"NO"])
{
NSLog(#"Button 2 was selected.");
}
else if([title isEqualToString:#"YES"])
{
NSLog(#"Button 1 was selected.");
// attended
[_eachEvent setHasATTENDED:[NSNumber numberWithBool:TRUE]];
// save
NSError *error = nil;
if (![_managedObjectContext save:&error])
{
NSLog(#"Error in saving");
}
}
}
in my DataManager class:
- (void) locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation {
//NSLog(#"MV_EventsDataManager new location: latitude %+.6f, longitude %+.6f\n", newLocation.coordinate.latitude, newLocation.coordinate.longitude);
for (Event *musicevent in [self loadTodaysEvents]) {
// distance
CLLocationDegrees lat = [musicevent.lat doubleValue];
CLLocationDegrees lon = [musicevent.longi doubleValue];
CLLocation *evLocation = [[CLLocation alloc] initWithLatitude:lat longitude:lon];
double distance = [evLocation distanceFromLocation:newLocation];
//NSLog(#"\t Calculated KM %# to %#", [NSString stringWithFormat:#"%.1f",(distance/1000.0)], musicevent.title);
// CLOSE !
if (distance <= 100) {
[[UIApplication sharedApplication] cancelAllLocalNotifications];
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.alertBody = #"Are u there!";
localNotification.soundName = UILocalNotificationDefaultSoundName;
localNotification.applicationIconBadgeNumber = 1; // increment
// NSDictionary *infoDict = [NSDictionary dictionaryWithObjectsAndKeys:#"Object 1", #"Key 1", #"Object 2", #"Key 2", nil];
// localNotification.userInfo = infoDict;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
}
}
}
Depending on how you setup the location manager, the delegate method locationManager:didUpdateToLocation:fromLocation: will typically be called once per second with location updates. So your code is posting local notifications over and over. You need to keep track of when you've posted a notification so you can avoid posting duplicates.

LocalNotification for iOS

I am implementing local notifications in my iOS app. Actually, I have a implementation with a method when i have created a notification :
-(void)setAlarmAction: (NSDate *) notificationDay days: (NSNumber *) day alert : (NSNumber * ) priority name:(NSString * ) nameNotification {
NSDate *notificationDate = notificationDay;
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
if (localNotification == nil) {
return;
}
localNotification.fireDate = notificationDate;
localNotification.timeZone = [NSTimeZone defaultTimeZone];
localNotification.alertBody = [NSString stringWithFormat: #"Quedan %# dias" , day];
localNotification.alertAction = #"Ver Documento";
localNotification.soundName = UILocalNotificationDefaultSoundName;
localNotification.applicationIconBadgeNumber = [[UIApplication sharedApplication]applicationIconBadgeNumber]+1; //aumenta en uno el numero de notificaciones
////////////
NSDictionary *infoDictionary = [NSDictionary dictionaryWithObject:#"notification" forKey:nameNotification]; //1º que se guarda , 2º con que clave
localNotification.userInfo = infoDictionary;
////////////
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:localNotification];
[[NSUserDefaults standardUserDefaults] setObject:data forKey:nameNotification];
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
// Get list of local notifications
NSArray *localNotifications = [[UIApplication sharedApplication] scheduledLocalNotifications];
for( UILocalNotification * local in localNotifications) {
NSLog(#"Notificacion: %# fecha :%#",local.alertBody,local.fireDate.description);
}
}
-(void) launchNotificacion:(Documento *)document {
self.txDate.text = document.text;
}
I want the app run in background and when it appear on the tabBar, i can push it and it go me to a concret view and launch a few data. I did it in the didFinishlaunchingWithOptions.
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
//self.viewDocumentForm
VTDocumentFormViewController *VTDocument = [[VTDocumentFormViewController alloc] initWithNibName:#"VTDocumentFormViewController" bundle:nil];
UILocalNotification *notification = [launchOptions objectForKey:
UIApplicationLaunchOptionsLocalNotificationKey];
if (notification) {
[self.window.rootViewController presentViewController: VTDocument animated:YES completion:nil];
Documento *reminderDocument = [NSEntityDescription insertNewObjectForEntityForName:#"Documento" inManagedObjectContext:self.managedObjectContext];
reminderDocument = [notification.userInfo objectForKey: key ];
[self.viewDocumentForm launchNotificacion:reminderDocument];
application.applicationIconBadgeNumber = notification.applicationIconBadgeNumber-1;
}
// Override point for customization after application launch.
return YES;
}
But it doesn't work and i don't know the reason. Please, help.
didFinishLaunchingWithOptions: with UIApplicationLaunchOptionsLocalNotificationKey in launchOptions will be invoked only if app was suspended/killed before localNotification.fireDate reached.
If you'r app is just in background (not killed) or active you'll got
application:didReceiveLocalNotification: fired
Also i don't see in your didFinishLaunchingWithOptions: where did you register user notification settings (for iOS8)… smth like:
if ([UIApplication instancesRespondToSelector:#selector(registerUserNotificationSettings:)]) {
UIUserNotificationType types = UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge;
UIUserNotificationSettings *mySettings =
[UIUserNotificationSettings settingsForTypes:types categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:mySettings];
}

Is NSNotificationCenter necessary to cancel UILocalnotficiation?

I want to cancel a UILocalnotification , when i cancel notification still the notification is being fired . I wanted to know do i have to call any delegate method in appdelegate to cancel notification .the code which i am using is executing correctly .but the notification is getting fired .
Should i use NSNotification center which has removeObserver method to cancel uilocalnotification.
Does UILocalnotification fires notification from the app or from the device.
UPDATE - This is how i am scheduling my notification
-(UILocalNotification *)scheduleNotification :(int)remedyID
{
NSString *descriptionBody;
NSInteger frequency;
UILocalNotification *notif = [[UILocalNotification alloc] init];
NSLog(#"%d",remedyID);
descriptionBody =[[self remedyDetailsForRemedyID:remedyID] objectForKey:#"RemedyTxtDic"];
frequency = [[[self remedyDetailsForRemedyID:remedyID] objectForKey:#"RemedyFrequency"]intValue];
NSArray *notificationFireDates = [self fireDatesForFrequency:frequency];
for (NSDate *fireDate in notificationFireDates)
{
notif.timeZone = [NSTimeZone defaultTimeZone];
notif.repeatInterval = NSDayCalendarUnit;
notif.alertBody = [NSString stringWithString:descriptionBody];
notif.alertAction = #"Show me";
notif.soundName = UILocalNotificationDefaultSoundName;
notif.applicationIconBadgeNumber = 1;
notif.fireDate = fireDate;
NSDictionary *userDict = [NSDictionary dictionaryWithObjectsAndKeys:notif.alertBody, #"kRemindMeNotificationDataKey", [NSNumber numberWithInt:remedyID],kRemindMeNotificationRemedyIDKey,
nil];
notif.userInfo = userDict;
[[UIApplication sharedApplication] scheduleLocalNotification:notif];
}
return notif;
}
Cancelling notification
- (void)cancelNotification:(int)remedyId
{
NSArray *notifications = [[UIApplication sharedApplication] scheduledLocalNotifications];
NSLog(#"Cancelling... Before %d",[[[UIApplication sharedApplication]scheduledLocalNotifications]count]);
for (UILocalNotification *notification in notifications)
{
int notifRemedyId = [[notification.userInfo objectForKey:#"kRemindMeNotificationRemedyIDKey"]intValue];
NSLog(#"remedyID : %d",remedyId);
NSLog(#"notifyId : %d",notifRemedyId);
if (remedyId == notifRemedyId) {
[[UIApplication sharedApplication] cancelLocalNotification:notification];
}
}
NSLog(#"Cancelling... After %d",[[[UIApplication sharedApplication]scheduledLocalNotifications]count]);
}
NSNotification center which has removeObserver method to cancel uilocalnotification.
NSNotificationCenter has nothing to do with UILocalNotification. I'm sorry that they both use "notification" somewhere in their names, but that is just coincidence really.
scheduledLocalNotifications will give you the list of all scheduled notifications and use
- (void)cancelLocalNotification:(UILocalNotification *)notification
or you can cancel them all using:
[[UIApplication sharedApplication] cancelAllLocalNotifications];
Edit :
NSString *notifRemedyId = #"notifRemedyId";
UILocalNotification *localnotif=[[UILocalNotification alloc]init];
NSDictionary *userDict = [NSDictionary dictionaryWithObjectsAndKeys:#"kRemindMeNotificationRemedyIDKey", kRemindMeNotificationRemedyIDKey,YOUR_REMEDYID,#"notifRemedyId",nil];
localnotif.userInfo = userDict;
[[UIApplication sharedApplication] scheduleLocalNotification:localnotif];
Cancel as :
for (UILocalNotification *aNotif in [[UIApplication sharedApplication] scheduledLocalNotifications]) {
if ([[aNotif.userInfo objectForKey: kRemindMeNotificationRemedyIDKey] isEqualToString:#"kRemindMeNotificationRemedyIDKey"]) {
if (remedyId == [[aNotif.userInfo objectForKey: kRemindMeNotificationRemedyIDKey] intValue]) {
[[UIApplication sharedApplication] cancelLocalNotification:aNotif];
break;
}
}
}
Hope it helps you.

iOS local notification was fired on wrong date time

I've created a old uilocalnotification, now, I want to update it, I searched on Google but there are no way to update the local notification. So, I decided to cancel it and create a new local notication:
- (void) cancelLocalNotificationByUserInfo: (NSDictionary *)dictInfo
{
UIApplication *application = [UIApplication sharedApplication];
NSArray *notifArr = [application scheduledLocalNotifications];
for (int i=0; i<notifArr.count; i++)
{
UILocalNotification* theNotif = (UILocalNotification *)[notifArr objectAtIndex:i];
if ([theNotif.userInfo isEqual:dictInfo])
{
[application cancelLocalNotification:theNotif];
}
}
}
- (void) addLocalNotification: (NSDate *) fireDate soundName: (NSString *) soundName
alertBody: (NSString *) alertBody infoDict: (NSDictionary *)infoDict
{
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
if (localNotif == nil)
return;
localNotif.fireDate = fireDate;
localNotif.timeZone = [NSTimeZone defaultTimeZone];
// Notification details
localNotif.alertBody = alertBody;
// Set the action button
localNotif.alertAction = #"Show me";
localNotif.hasAction = YES;
localNotif.applicationIconBadgeNumber = 1;
localNotif.soundName = soundName;
localNotif.userInfo = infoDict;
// Schedule the notification
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
[localNotif release];
}
But, everytime, I execute the addLocalNotification method, the old local notification is fired immediately. Please help me!

Resources