I am trying to implement local notification in my application. I don't know how to do properly, below code I am using for new data arrival process, here after how to implement Notification process and I need notifications during both foreground and background modes.
Below I had successfully background fetching process for new data arrival checking method
// Value matching and trying to get new data
[live_array removeObjectsInArray:stored_array];
// if you require result as a string
NSString *result = [stored_array componentsJoinedByString:#","];
NSLog(#"New Data: %#", result); // objects as string:
Above code finally giving some string value...Once the value came I want to show the notification. Everything I am doing is in the App Delegate.
1) When the app is closed, schedule a local notification that will fire in 24 hours
- (void)applicationDidEnterBackground:(UIApplication *)application
{
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.fireDate = [[NSDate date] dateByAddingTimeInterval:60*60*24];
notification.alertBody = #"24 hours passed since last visit :(";
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
}
2) if the app is opened (before the local notification fires), cancel the local notification
- (void)applicationDidBecomeActive:(UIApplication *)application
{
[[UIApplication sharedApplication] cancelAllLocalNotifications];
}
//For local Notification
first thing we need to do is register the notifications.
// New for iOS 8 - Register the notifications
UIUserNotificationType types = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
UIUserNotificationSettings *mySettings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:mySettings];
Now let’s create the notification itself
UILocalNotification *notification = [[UILocalNotification alloc] init];
if (notification)
{
notification.fireDate = _datePicker.date;
NSDate *fireTime = [[NSDate date] addTimeInterval:10]; // adds 10 secs
notification.fireDate = fireTime;
notification.alertBody = #"Alert!";
notification.timeZone = [NSTimeZone defaultTimeZone];
notification.applicationIconBadgeNumber = 1;
notification.soundName = UILocalNotificationDefaultSoundName;
switch (_frequencySegmentedControl.selectedSegmentIndex) {
case 0:
notification.repeatInterval = NSCalendarUnitDay;
break;
case 1:
notification.repeatInterval = NSCalendarUnitWeekOfYear;
break;
case 2:
notification.repeatInterval = NSCalendarUnitYear;
break;
default:
notification.repeatInterval = 0;
break;
}
notification.alertBody = _customMessage.text;
Once we have the notification created we need to schedule it with the app.
// this will schedule the notification to fire at the fire date
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
// this will fire the notification right away, it will still also fire at the date we set
[[UIApplication sharedApplication] presentLocalNotificationNow:notification];
If we leave things the way they are now a notification will only appear on screen if the app is in the background. In order to display something when the app is in the foreground and a notification fires we need to implement a method in the app delegate.
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
UIAlertView *alertView = [[UIAlertView alloc]initWithTitle:#"Notification Received" message:notification.alertBody delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alertView show];
}
We added a icon badge to our app, and this icon badge will only display when the app is in the background. Generally you want to dismiss the icon once a user has opened the app and seen the notification. We’ll need to handle this in the app delegate as well.
These two methods will take care of it.
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
NSLog(#"%s", __PRETTY_FUNCTION__);
application.applicationIconBadgeNumber = 0;
}
- (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.
NSLog(#"%s", __PRETTY_FUNCTION__);
application.applicationIconBadgeNumber = 0;
}
iOS 10 by Apple document:
UNMutableNotificationContent* content = [[UNMutableNotificationContent alloc] init];
content.title = [NSString localizedUserNotificationStringForKey:#"Hello!" arguments:nil];
content.body = [NSString localizedUserNotificationStringForKey:#"Hello_message_body"
arguments:nil];
content.sound = [UNNotificationSound defaultSound];
// Deliver the notification in five seconds.
UNTimeIntervalNotificationTrigger* trigger = [UNTimeIntervalNotificationTrigger
triggerWithTimeInterval:5 repeats:NO];
UNNotificationRequest* request = [UNNotificationRequest requestWithIdentifier:#"FiveSecond"
content:content trigger:trigger];
// Schedule the notification.
UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
[center addNotificationRequest:request withCompletionHandler:nil];
Related
I am generating Local notification when Push notification(Actionable) are received but app is closed or in background. I have used following code to generate local notification in objective-c.
- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void (^)())completionHandler {
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
// localNotification.fireDate = [NSDate date];
localNotification.timeZone = [NSTimeZone defaultTimeZone];
localNotification.alertBody = #"Security settings enabled, tap to start the application";
localNotification.category = #"LOCAL_NOTIFICATION"; // Same as category identifier
// [[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
[[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];
}
1.When i drag notification trey down(Notification Center) not from alert it generate local notification fine in 1 sec.
2.But while press action from alert(while at home) it
it takes 3-4 seconds for local notification to appear.
Why there is time difference between action from alert(press action from home) and Notification center(swipe down notification trey)
generating local notification?
How to make it faster? Thanks in advance.
Try to use the presentLocalNotificationNow method instead of scheduleLocalNotification to make your notification fire instantly:
[[UIApplication sharedApplication] presentLocalNotificationNow:localNotification];
I have initialize local notification for every 30 seconds. and i want to stop repeating it once user has pressed button for stop Local Notification.
problem is i couldnt find a way of doing it. it keeps repeating every 30 seconds
This is how i have sheducled localnotification
// Schedule the notification
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:30];
localNotification.alertBody = #"Testing Repeating Local Notification";
localNotification.applicationIconBadgeNumber = 1;
localNotification.timeZone = [NSTimeZone defaultTimeZone];
localNotification.soundName = UILocalNotificationDefaultSoundName;
localNotification.repeatCalendar = [NSCalendar currentCalendar];
localNotification.repeatInterval = kCFCalendarUnitSecond;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
I have tried [[UIApplication sharedApplication] cancelAllLocalNotifications]; . but it dosent work.
Can you set repeatInterval to 0. According to documentation if it is set to zero notification will be fired once. So when stop button is pressed you can do following
localNotification.repeatInterval = 0;
[[UIApplication sharedApplication] cancelAllLocalNotifications];
I solved it.
just removed localNotification.repeatCalendar = [NSCalendar currentCalendar]; from above code.
you can remove notification when you get notification in application active state.
just like
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
if (application.applicationState == UIApplicationStateActive)
{
NSLog(#"Application is active");
/*
...
do some process
...
*/
//remove notification
[application cancelLocalNotification:notification];
}
else
{
NSLog(#"Application is inactive");
}
}
I have an app where I need to send a UILocationNotification when the app is not in the foreground / Active. If I have my code to do so, it will not send until the app is opened and is active.
Here is my function:
- (void)setLocalNotificationForType:(SPKLocalNotificationType)notificationType fromUser:(NSString *)userName withMessageText:(NSString *)msgText {
UILocalNotification *notif = [[UILocalNotification alloc] init];
notif.userInfo = #{#"handle": _convoHandle, #"room": _convoName};
notif.fireDate = [NSDate date];
notif.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber] + 1;
notif.soundName = UILocalNotificationDefaultSoundName;
notif.timeZone = [NSTimeZone defaultTimeZone];
if (notificationType == 1) { // message
notif.alertBody = [NSString stringWithFormat:#"#%# said: \"%#\"", userName, msgText];
} else if (notificationType == 2) { // image
notif.alertBody = [NSString stringWithFormat:#"#%# sent an image", userName];
} else {
return;
}
if ([[UIApplication sharedApplication] applicationState] != UIApplicationStateActive) {
[[UIApplication sharedApplication] presentLocalNotificationNow:notif];
}
}
Update:
It now seems that the problem is that the connection to the server is being "paused" while the app is in the background. Once I then open the app all the data comes in at once. I am using SocketRocket for connecting to my Node.js Primus web socket server. Is this something that normally happens? This is my first time using SocketRocket so I'm not sure.
Update:
I have also enabled Remote Notifications for Background Modes, I have also registered for remote notifications, and on the device, I have also made sure that "banners" and "badges" are enabled.
Update:
I have additionally set the web socket to use a background queue.
[webSocket setDelegateOperationQueue:[NSOperationQueue new]];
The connection is still being paused.
Thanks!
Edit: It looks like SocketRocket uses the main dispatch queue by default, which runs on the application's main thread. When the app is backgrounded, processing on the main thread stops, so it would be worth trying to move the work to a background thread in a background operation queue.
On your SRWebSocket object, try calling:
[webSocket setDelegateOperationQueue:[NSOperationQueue new]];
Without checking the docs, perhaps setting timeZone and fireDate on the UILocalNotification is interfering. You don't need those if you're going to pass the notification to presentLocalNotificationNow:.
I have also found that, even if you're using local notifications exclusively, you must:
Enable Remote notifications for your target on the Capabilities tab under Background Modes
Enable either alerts or banners in the Settings app, in Notification Center settings.
A sample event handler for a background fetch:
- (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler
{
UIBackgroundFetchResult result = UIBackgroundFetchResultNoData;
// ... perform a network request
if (successfulNetworkRequest) {
UILocalNotification* localNotification = [UILocalNotification new];
localNotification.alertAction = #"View";
localNotification.alertBody = #"Stuff";
localNotification.soundName = UILocalNotificationDefaultSoundName;
localNotification.applicationIconBadgeNumber = 1;
localNotification.userInfo = #{#"stuff": #"other stuff"};
[application presentLocalNotificationNow:localNotification];
result = UIBackgroundFetchResultNewData;
} else {
result = UIBackgroundFetchResultFailed;
}
completionHandler(result);
}
I am afraid you are misunderstanding of local notification. I guess what you should do is registering a notification in the future and send it some time after user clicked the home button. But in your code, you registered a alert in CURRENT TIME and did some thing on the notification (sorry but I don't know what you want to do in your code).
You could change it like this to make a sense:
- (void)setLocalNotificationForType:(SPKLocalNotificationType)notificationType fromUser:(NSString *)userName withMessageText:(NSString *)msgText {
UILocalNotification *notif = [[UILocalNotification alloc] init];
notif.userInfo = #{#"handle": _convoHandle, #"room": _convoName};
//Set the fire time 10 seconds later
notif.fireDate = [[NSDate date] dateByAddingTimeInterval:10];
notif.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber] + 1;
notif.soundName = UILocalNotificationDefaultSoundName;
notif.timeZone = [NSTimeZone defaultTimeZone];
if (notificationType == 1) { // message
notif.alertBody = [NSString stringWithFormat:#"#%# said: \"%#\"", userName, msgText];
} else if (notificationType == 2) { // image
notif.alertBody = [NSString stringWithFormat:#"#%# sent an image", userName];
} else {
return;
}
//Register this notification
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
}
And in your app delegate's -applicationDidEnterBackground:, call your -setLocalNotificationForType:fromUser:withMessageText: method to make and register a notification. Then you can expect a local notification 10s after you click the home button.
What is the difference between presentLocalNotificationNow and scheduleLocalNotification.
For the both following function is showing notification after 1 second
-(void)showLocalNotification:(NSNotification *)notification {
NSString *msg = #"test message";
[[UIApplication sharedApplication] cancelAllLocalNotifications];
UILocalNotification *_localNotification = [[UILocalNotification alloc]init];
_localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:1];
_localNotification.timeZone = [NSTimeZone defaultTimeZone];
_localNotification.alertBody = msg;
_localNotification.soundName = UILocalNotificationDefaultSoundName;
_localNotification.applicationIconBadgeNumber = [[UIApplication sharedApplication] applicationIconBadgeNumber]+1;
[[UIApplication sharedApplication] scheduleLocalNotification:_localNotification];
// or
//[[UIApplication sharedApplication] presentLocalNotificationNow:_localNotification];
}
If the application is running in the background, the local notification will not get an alert or sound, as it is directly received by the application. In that case, you need to present the notification using presentLocalNotificationNow.
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
UIApplicationState applicationState = application.applicationState;
if (applicationState == UIApplicationStateBackground) {
[application presentLocalNotificationNow:notification];
}
}
From Apple Documentation:
Once you have created an instance of UILocalNotification, you schedule
it using one of two methods of the UIApplication class:
scheduleLocalNotification: or presentLocalNotificationNow:. The former
method use the fire date to schedule delivery; the latter method
presents the notification immediately, regardless of the value of
fireDate. You can cancel specific or all local notifications by
calling cancelLocalNotification: or cancelAllLocalNotifications,
respectively.
There's no difference right here, but using scheduleLocalNotification you can schedule it at whatever time you want, not only in one second.
And, of corse, nobody promises you that presentLocalNotificationNow will show one in exactly one second, not in 0.5 or 2.0 in iOS 8, for example.
I am trying to run some function every n-minutes when app is not running.
I thing local notification is suitable for that, but I have one problem.
If I set local notification as :
-(void)notification{
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
if (localNotif == nil)
return;
localNotif.fireDate = [[NSDate date] dateByAddingTimeInterval:15];
//localNotif.timeZone = [NSTimeZone defaultTimeZone];
// Notification details
localNotif.alertBody = #"marko";
// Set the action button
localNotif.alertAction = #"View";
localNotif.soundName = UILocalNotificationDefaultSoundName;
localNotif.applicationIconBadgeNumber = 1;
// Specify custom data for the notification
NSDictionary *infoDict = [NSDictionary dictionaryWithObject:#"someValue" forKey:#"someKey"];
localNotif.userInfo = infoDict;
// Schedule the notification
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
}
The notification is fired every time and then do:
- (void)application:(UIApplication *)app didReceiveLocalNotification:(UILocalNotification *)notif {
NSLog(#"Recieved Notification %#",notif);
}
What I would want is to after 15s first fire some function and if function return YES then play sound and put badge on it.
How to do that?
If the application is foremost and visible when the system delivers the notification, no alert is shown, no icon is badged, and no sound is played. However, the application:didReceiveLocalNotification: is called if the application delegate implements it.
Make sure you are testing in device.