I send a LocalNotification like this:
UILocalNotification *notification = [UILocalNotification new];
notification.alertBody = #"Hello, open me";
notification.userInfo = #{#"TheKey": #"www.stackoverflow.com"};
notification.soundName = UILocalNotificationDefaultSoundName;
[[UIApplication sharedApplication] presentLocalNotificationNow:notification];
and in AppDelegate I do use:
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
NSDictionary *userInfo = notification.userInfo;
NSURL *siteURL = [NSURL URLWithString:[userInfo objectForKey:#"TheKey"]];
[[UIApplication sharedApplication] openURL:siteURL];
}
It opens the URL in new broswer window but it takes like 5-10 seconds for the app to take that action. Is it possible to open browser immediatly when LocalNotification is opened?
On iOS 7 and prior your approach would indeed be the only one. This is because UILocalNotification is only used to open your app, i.e. call the AppDelegate's method application:didReceiveLocalNotification:. So, the first place indeed for you to perform any actions would be that method.
However, with iOS 8 interactive notifications have been introduced. These allow the user to perform a specified action without opening the app.
In the screenshot you see that the user just received a notification and now has the option to perform certain actions on it, without actually going back into the app. You can find a great tutorial on how to implement interactive notifications here!
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 am making an app in which user select time and video. When notification fire than I want that the select video should be played . How can i achieve that?
Here is my notification code.
-(void) scheduleLocalNotificationWithDate:(NSDate *)fireDate
{
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
localNotif.fireDate = fireDate;
localNotif.timeZone = [NSTimeZone localTimeZone];
localNotif.alertBody = #"Time to wake Up";
localNotif.alertAction = #"Show me";
localNotif.soundName = #"Tick-tock-sound.mp3";
localNotif.applicationIconBadgeNumber = 1;
localNotif.repeatInterval = NSCalendarUnitDay;
NSLog(#" date %lu",kCFCalendarUnitDay);
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
}
Any Syggestion?
Your code for scheduling a local notification looks good. Probably you should also add some data in the userInfo property of the local notification, so that when it fires, you can check that property and do something different (play a specific video) according to the data inside the userInfo.
Example:
NSDictionary *infoDict = [NSDictionary dictionaryWithObject:#"video1" forKey:#"videoName"];
localNotif.userInfo = infoDict;
Make sure that you also request user permission for using local notifications, otherwise the local notification will not fire.
Example:
UIUserNotificationType types = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
UIUserNotificationSettings *mySettings = [UIUserNotificationSettings settingsForTypes:types categories:nil];
[[UIApplication sharedApplication] registerUserNotificationSettings:mySettings];
Now you need to handle the firing of the local notification when your app is in the 3 states: foreground, background/suspended and not running.
The app is running in the foreground. The local notification fires at the date you set it to. The following delegate method will get called by the system in AppDelegate:
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
NSString *videoName = [notification.userInfo objectForKey:#"videoName"];
//do something, probably play your specific video
}
The app is running in the background or is suspended. The local notification is shown to the user (it fired at the date you set it to) and the user taps on it. The same delegate method as above (didReceiveLocalNotification) will get called by the system in AppDelegate:
The app is not running, the local notification is shown to the user (it fired at the date you set it to) and the user taps on it. The following delegate method will get called by the system in AppDelegate:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UILocalNotification *localNotif = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (localNotif)
{
//the app was launched by tapping on a local notification
NSString *videoName = [localNotif.userInfo objectForKey:#"videoName"];
// play your specific video
} else {
// the app wasn't launched by tapping on a local notification
// do your regular stuff here
}
}
I would recommend reading Apple's documentation regarding working with local notifications.
You can use the Media Player framework as recommended in Glorfindel's answer and you can find an example for playing a video in this StackOverflow answer.
Once the user opens your local notification, your app will be launched, and the - application:didFinishLaunchingWithOptions: of your UIApplicationDelegate will be called. The options dictionary will contain a UIApplicationLaunchOptionsLocalNotificationKey key, which contains the UILocalNotification. That should give you enough information to determine which video needs to be played, which you can do with the Media Player framework.
My title might not accurately depict my question, so I apologize. I have looked for a solution to creating this level of functionality but I am unable to find it.
I am creating a VoIP application for iOS 8. When a user receives a call I am displaying a notification with a 12 second ringtone. While this notification is in progress if the call disconnects I want the Incoming Call notification to disappear and display a Missed Call notification immediately. This level of functionality is possible because Viber does it.
Currently, I am sending a silent push notification when a Incoming Call is available. This is my payload...
aps = {
"content-available" = 1;
};
category = INCOMING;
from = "+15555554220";
Upon receiving the silent push I am creating a Local Notification like this ...
if ([userInfo[#"category"] isEqualToString:#"INCOMING"]) {
NSLog(#"application: didReceiveRemoteNotification: fetchCompletionHandler: Incoming Call Notification Received");
NSLog(#"application: didReceiveRemoteNotification: fetchCompletionHandler: Sending Local Notification For Incoming Call");
// Get Caller Contact Info
NSDictionary *contact = [self findContactInfoForNumber:userInfo[#"from"]];
NSString *message = [NSString stringWithFormat:#"Incoming Call: %#",userInfo[#"from"]];
if (contact != nil) {
message = [NSString stringWithFormat:#"Incoming Call: %# %#",contact[#"firstName"],contact[#"lastName"]];
}
UILocalNotification *notification = [[UILocalNotification alloc] init];
NSMutableDictionary *infoDict = [NSMutableDictionary dictionaryWithObject:#"Incoming Call" forKey:#"type"];
notification.userInfo = infoDict;
notification.category = #"INCOMING_CALL_CATEGORY";
notification.fireDate = [NSDate dateWithTimeIntervalSinceNow:1];
notification.alertBody = message;
notification.timeZone = [NSTimeZone defaultTimeZone];
notification.soundName = #"ring.m4a";
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
}
Then, once the call is disconnected I am sending another silent push notification for a missed call...
aps = {
"content-available" = 1;
};
category = MISSED;
Once received I am canceling all local notifications like this...
if ([userInfo[#"category"] isEqualToString:#"MISSED"]) {
NSLog(#"application: didReceiveRemoteNotification: fetchCompletionHandler: Missed Call Notification Received");
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
[[UIApplication sharedApplication] cancelAllLocalNotifications];
}
The issue I am encountering is that on the lock screen it behaves exactly the way I want it to. I receive the incoming call notification and when the caller hangs up that notification immediately disappears from notification center and a missed call notification is there in the place of it. However when the phone is on the home screen. A banner is shown and then it plays the whole ringtone then displays the missed call. Does anyone know the reason why this is happening? Does anyone have any solutions to achieve this level of functionality? Like I said before the app Vider is a prime example of what I want my app to do.
Thanks you in advance.
Im working on an app that does some computationally heavy tasks that take a long time. I want to notify the user with a local push notification when the task is done. Is this possible? The only information I have been able to find online is to do with triggering notifications at certain times/dates or if the app has entered the background or terminated, all of which is done in the appDelegate. Is there a way to do this in my own classes?
Thanks.
I'm not 100% certain you're looking for a UILocalNotification example because the post title mentions push notifications. Either way, you can schedule local notifications from any class you want
- (void)throwLocalNotificationWithMessage:(NSString*)message {
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
NSDate *now = [NSDate date];
localNotification.fireDate = now;
localNotification.alertBody = message;
localNotification.soundName = UILocalNotificationDefaultSoundName;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
[UIApplication sharedApplication].applicationIconBadgeNumber++;
}
Also, for my needs I throw these local notifications when region monitoring detects boundary enter/exit changes. This code runs while my app is in the background, as well, and in that case they appear like push notifications.
The above answer by Aaron works fine but don't forget to ask permission for Local Notification. In my case case I ask permission at AppDelegate under -
(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
and here is the code for iOS8 and iOS9
if ([application respondsToSelector:#selector(registerUserNotificationSettings:)]) {
[application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound categories:nil]];
}
I got my push notification successfully in both background and foreground but my problem is when my application is in active state/foreground and push notification is arrived then i show this pushnotification message on alertview using didReceiveRemoteNotification method,
My alert view have two buttons
1) later
2) Ok.
If I press 1) "later" button then I want add this pushnotification message in notification area so after some time user can see and tap on that particular push notification and go with that and that record of push notification will remove from notification area.
This is not possible. There is no API to access notification are of iOS.
Alternative
What near alternative you can try is Local Notification. When user select later set Local Notification for that thing. You can add this Local Notification when user leave your app so that you don't get notification while user is continue with your application.
Better Approach
The most general approach for this problem is Notification screen in app. Your application has one screen which has list of received notification so that user can check that in you app. I suggest you to go with this. Because this is most common and clear idea.
You need to implement core data for Notifications but it can only happen when your Application is is Active state.
1-create a new identity everytime a new notification arrive.
2-save it.
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
NSDictionary *Notification = userInfo;
NSString *title = [(NSDictionary*)[(NSDictionary*)[Notification valueForKey:#"aps"] valueForKey:#"alert"] valueForKey:#"title"];
NSString *body = [(NSDictionary*)[(NSDictionary*)[Notification valueForKey:#"aps"] valueForKey:#"alert"] valueForKey:#"body"];
XXNotification *objNotification = [XXNotification create];
objNotification.title = title;
objNotification.detail = body;
[XXNotification save:nil];
NSArray *arrNotification =[XXNotification allUnRead:nil];
[UtilityFunctions setApplicationBadgeNumber:[arrNotification count]];//Utility functions is my class for common functions.
if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateActive)
{
[UtilityFunctions showAlertView:title message:body delegate:self cancelButtonTitle:#"Ok" otherButtonTitle:#"Cancel" withTag:99 withAccessibilityHint:[NSString stringWithFormat:#"%#:|:%#", title,body]];
}
else if ([[UIApplication sharedApplication] applicationState] == UIApplicationStateInactive || [[UIApplication sharedApplication] applicationState] == UIApplicationStateBackground)
{
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.userInfo = userInfo;
localNotification.soundName = UILocalNotificationDefaultSoundName;
localNotification.alertBody = body;
localNotification.fireDate = [NSDate date];
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
if (![IsLocationSaved isEqualToString:#"NO"])
{
[[NSNotificationCenter defaultCenter]postNotificationName:kNotificationForShowingNotification object: nil userInfo:nil];
}
}
}
On showing the UIAlertView, on its click event either delete that notification in DB or make a bool in it as isRead and make it YES. then save it,
On Notifications list Query the notification from DB or only those whose isRead = NO.
That is the way I did it in My Application.