I need to run an NSTimer in an app even after the user minimizes the app. The Timer is used to hit a web service every 15 seconds and after 4 minutes I need to perform certain navigations. How can this be done?
I know this question has been asked earlier too but I have not been able to find an appropriate answer.
You need a reason for it to be possible.
If it's for navigation app, VOIP, or just for background downloads (in some cases), it's possible.
But otherwise, you can't do it.
Before you proceed, think about why it isn't easy to make a timer run when the app is in the background. It's because it empties the phone's battery. You get unhappy customers if you do that. Which Apple doesn't care much about, but Apple gets unhappy customers, which they care about a lot. Under Settings -> Battery Apple will tell the user which app used how much energy in the last 24 hours / 6 days, so people can find your app if it does waste energy in the background and throw it out.
You can configure you app to run in the background, but you have no control over how frequently iOS calls you app in the background.
I know this is a really bad solution and misuse of the service, but you could initiate a background file download and make your server to send data so slowly that it takes about 4 minutes. iOS will report to your app when the transfer is complete. If your app is not terminated iOS also reports the download progress to your app. But you can't open the app ui when the transfer is complete if the app is not in the foreground.
Create the configuration object using the
backgroundSessionConfigurationWithIdentifier: method of
NSURLSessionConfiguration.
Set the value of the configuration object’s
sessionSendsLaunchEvents property to YES.
if your app starts transfers
while it is in the foreground, it is recommend that you also set the
discretionary property of the configuration object to YES.
Configure
any other properties of the configuration object as appropriate.
Use
the configuration object to create your NSURLSession object.
When all of the tasks associated with a background session are
complete, the system relaunches a terminated app (assuming that the
sessionSendsLaunchEvents property was set to YES and that the user did
not force quit the app) and calls the app delegate’s
application:handleEventsForBackgroundURLSession:completionHandler:
method.
https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html
AppDelegate.h // using local notification to get some function call
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[self getNotificationPermission];
return YES;
}
This method used for permission
-(void)getNotificationPermission{
// Accept Action
UIMutableUserNotificationAction *acceptAction = [[UIMutableUserNotificationAction alloc] init];
acceptAction.identifier = #"Accept";
acceptAction.title = #"Yes i am OK";
acceptAction.activationMode = UIUserNotificationActivationModeBackground;
acceptAction.destructive = NO;
acceptAction.authenticationRequired = NO;
// Reject Action
UIMutableUserNotificationAction *rejectAction = [[UIMutableUserNotificationAction alloc] init];
rejectAction.identifier = #"Reject";
rejectAction.title = #"On i am Not OK";
rejectAction.activationMode = UIUserNotificationActivationModeBackground;
rejectAction.destructive = YES;
rejectAction.authenticationRequired = YES;
// Reply Action
UIMutableUserNotificationAction *replyAction = [[UIMutableUserNotificationAction alloc] init];
replyAction.identifier = #"Reply";
replyAction.title = #"Reply";
replyAction.activationMode = UIUserNotificationActivationModeForeground;
replyAction.destructive = NO;
replyAction.authenticationRequired = YES;
// Email Category
UIMutableUserNotificationCategory *emailCategory = [[UIMutableUserNotificationCategory alloc] init];
emailCategory.identifier = #"Email";
[emailCategory setActions:#[acceptAction,rejectAction,replyAction] forContext:UIUserNotificationActionContextDefault];
[emailCategory setActions:#[acceptAction,rejectAction] forContext:UIUserNotificationActionContextMinimal];
// Download Action
UIMutableUserNotificationAction *downloadAction = [[UIMutableUserNotificationAction alloc] init];
downloadAction.identifier = #"Download";
downloadAction.title = #"Download";
downloadAction.activationMode = UIUserNotificationActivationModeForeground;
downloadAction.destructive = NO;
downloadAction.authenticationRequired = YES;
UIMutableUserNotificationAction *cancelAction = [[UIMutableUserNotificationAction alloc] init];
cancelAction.identifier = #"Cancel";
cancelAction.title = #"Cancel";
cancelAction.activationMode = UIUserNotificationActivationModeForeground;
cancelAction.destructive = YES;
cancelAction.authenticationRequired = YES;
// Image Category
UIMutableUserNotificationCategory *imageCategory = [[UIMutableUserNotificationCategory alloc] init];
imageCategory.identifier = #"Image";
[imageCategory setActions:#[downloadAction,cancelAction] forContext:UIUserNotificationActionContextDefault];
[imageCategory setActions:#[downloadAction,cancelAction] forContext:UIUserNotificationActionContextMinimal];
NSSet *categories = [NSSet setWithObjects:emailCategory,imageCategory, nil];
UIUserNotificationType notificarionType = UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert;
// Register notification types and categories
UIUserNotificationSettings *notificationSettings = [UIUserNotificationSettings settingsForTypes:notificarionType categories:categories];
[[UIApplication sharedApplication] registerUserNotificationSettings:notificationSettings];
// This line of code is required for remote push notification
//[[UIApplication sharedApplication] registerForRemoteNotifications];
}
-(void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings{
//UIUserNotificationType notificationtype = [notificationSettings types];
}
// You can check the current user notifiartions settings whenever you need it
-(void)getReadyForNotification{
//UIUserNotificationSettings *settings = [[UIApplication sharedApplication] currentUserNotificationSettings];
//[self checkSettings:settings];
}
// When appliation is in foregrounf this methid will get caled if you have scheduled a local notification
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification{
//CLRegion *region = notification.region;
if ([notification.category isEqualToString:#"Image"]) {
NSLog(#"Image category notification is presented to the user");
}else if([notification.category isEqualToString:#"Email"]){
NSLog(#"Email category notification is presented to the user");
}
}
-(void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forLocalNotification:(UILocalNotification *)notification completionHandler:(void (^)())completionHandler{
if ([identifier isEqualToString:#"Accept"]) {
[self printAlert:#"Accept"];
}else if ([identifier isEqualToString:#"Reject"]) {
[self printAlert:#"Reject"];
}else if ([identifier isEqualToString:#"Reply"]) {
[self printAlert:#"Reply"];
}else if ([identifier isEqualToString:#"Download"]) {
[self printAlert:#"Download"];
}else if ([identifier isEqualToString:#"Cancel"]) {
[self printAlert:#"Cancel"];
}
completionHandler();
}
-(void)printAlert:(NSString *)title
{
NSLog(#"%# button is selected",title);
if ([title isEqualToString:#"Accept"])
{
}
else if ([title isEqualToString:#"Reject"])
{
}
}
// Callback for remote notification
-(void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void (^)())completionHandler{
NSLog(#"handleActionWithIdentifier forRemoteNotification");
}
Set Local Notification on ViewController
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = [NSDate dateWithTimeIntervalSinceNow:10];
localNotification.alertBody = #"How you are Feeling Today ?";
localNotification.category = #"Email"; // This should match categories identifier which we have defined in App delegate
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
Using this code you will Get local notification after every cycle of time period if user select notification in foreground then open app in particular stage or screen you want. this code is also not breaching apple guidelines.
Related
Is there way to send local notification to the app from the app?
I need to send notification my app users every morning. So, can I add some code to the app, so after user launch that, every morning he or she will get badge/notification?
You can add local notifications to your iOS app by doing the following:
Step One
Register for local notifications in your App Delegate:
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Register the app for local notifcations.
if ([application respondsToSelector:#selector(registerUserNotificationSettings:)]) {
[application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert | UIUserNotificationTypeBadge | UIUserNotificationTypeSound categories:nil]];
}
// Setup the local notification check.
UILocalNotification *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
// Check if a notifcation has been received.
if (notification) {
dispatch_async(dispatch_get_main_queue(), ^{
// Run the notifcation.
// Call your own custom method from here.
// Use [notification.userInfo valueForKey:#"notification_id"] to get the associated notification id (You will need to assign an ID, when creating the notification).
});
}
// Ensure the notifcation badge number is hidden.
application.applicationIconBadgeNumber = 0;
return YES;
}
Step Two
Use the following method to create the local notification:
-(void)saveNotification:(NSString *)description :(NSString *)notificationID :(BOOL)locationCheck {
// Create the notification info dictionary
// and set the notification ID string.
NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] init];
[userInfo setObject:notificationID forKey:#"notification_id"];
// Setup the local notification.
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
// Set the notification ID and type data.
localNotification.userInfo = userInfo;
// Set the notification description.
localNotification.alertBody = [NSString stringWithFormat:#"%#", description];
// Set the sound alert MP3 file.
localNotification.soundName = [NSString stringWithFormat:#"Notification_sound_file.mp3"];
// Set the date for the notification or set the
// location depending on the notification type.
if (locationCheck == NO) {
// Fire date of your choice.
NSDate *yourFireDate;
// Set the reminder date.
double interval = [yourFireDate timeIntervalSinceNow];
localNotification.fireDate = [[NSDate date] dateByAddingTimeInterval:interval];
localNotification.timeZone = [NSTimeZone systemTimeZone];
// Set the notifcation repeat interval.
localNotification.repeatInterval = 0; // No repeat.
//localNotification.repeatInterval = NSCalendarUnitHour; // Every hour.
//localNotification.repeatInterval = NSCalendarUnitDay; // Every day.
//localNotification.repeatInterval = NSCalendarUnitWeekOfYear; // Once a week.
//localNotification.repeatInterval = NSCalendarUnitMonth; // Once a month.
//localNotification.repeatInterval = NSCalendarUnitYear; // Once a year.
}
else if (locationCheck == YES) {
// Set the locaton to the selected address co-ordinates.
CLLocationCoordinate2D coordinates = CLLocationCoordinate2DMake(latitude, longitude);
CLCircularRegion *region = [[CLCircularRegion alloc] initWithCenter:coordinates radius:100 identifier:[NSString stringWithFormat:#"region_%#", notificationID]];
// Set the notification to be presented
// when the user arrives at the location.
[region setNotifyOnEntry:YES];
[region setNotifyOnExit:NO];
// Set the notification location data.
[localNotification setRegion:region];
[localNotification setRegionTriggersOnce:NO];
}
// Save the local notification.
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
}
You will need to create your own unique id, in order to use this method. The id is important, because it will help you to distinguish between notifications (should you need to perform a specific action depending on the notification).
You can call the above method like so:
[self saveNotification:#"test notification hello world" :#"unique id" :NO];
Don't forget to replace latitude and longitude with your descried co-ordianted (if you need location based local notifications).
Step Three
If the app is currently open (in the foreground or via multitasking), you will need to implement another method in your app delegate, in order to handle notifications:
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
// Check if a notifcation has been received.
if (application.applicationState == UIApplicationStateInactive) {
// You app in running in the background but will be active,
// should the user tap the iOS notification banner.
// Call your own custom method from here.
// Use [notification.userInfo valueForKey:#"notification_id"] to get the associated notification id (You will need to assign an ID, when creating the notification).
}
else if (application.applicationState == UIApplicationStateActive) {
// The app is open in the foreground
// you will need to display an alert or banner
// in your app to alert the user.
// Call your own custom method from here.
// Use [notification.userInfo valueForKey:#"notification_id"] to get the associated notification id (You will need to assign an ID, when creating the notification).
}
// Ensure the notifcation badge number is hidden.
application.applicationIconBadgeNumber = 0;
}
A few other points to keep in mind
You can only set a maximum of 64 local notifications.
(Notifications which repeat are counted as one local notification). https://developer.apple.com/library/ios/documentation/iPhone/Reference/UILocalNotification_Class/
A local notification cannot have a fireDate and location region. If you want the same notification to appear at a given time and location, you will have to create 2 separate local notifications with the same description (one with a date and the other with the location).
You can use the following methods to delete all local notifications (or a specific one):
-(void)deleteAllNotifications {
// Delete all the local notifications.
[[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
[[UIApplication sharedApplication] cancelAllLocalNotifications];
}
-(void)deleteSpecificNotification:(NSString *)inputID {
// Get the notification(s) data.
NSArray *notificationData = [[UIApplication sharedApplication] scheduledLocalNotifications];
// Loop through all the local notifcations and delete
// all the notifications that match the input id string.
for (int loop = 0; loop < [notificationData count]; loop++) {
// Get the notification object.
UILocalNotification *localNotification = [notificationData objectAtIndex:loop];
// If the notification id matches the input id then delete it.
if ([[localNotification.userInfo objectForKey:#"notification_id"] isEqualToString:inputID]) {
[[UIApplication sharedApplication] cancelLocalNotification: localNotification];
}
}
}
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];
Im trying to implement the local notification to my app and I implemented the local notification but the problem is .... I'm not getting the Notification BANNER and SOUND when my app is in the foreground. But it is working good when my app is in background.
How to bring the notification banner and sound in foreground.. Is that possible?
this is my piece of code...
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Handle launching from a notification
UILocalNotification *locationNotification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if (locationNotification) {
// Set icon badge number to zero
application.applicationIconBadgeNumber = 0;
}
}
- (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo
{
if (application.applicationState == UIApplicationStateActive ) {
NSLog(#"it entered active push");
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.userInfo = userInfo;
localNotification.soundName = UILocalNotificationDefaultSoundName;
localNotification.alertBody = userInfo[#"aps"][#"alert"][#"body"];
localNotification.alertLaunchImage= userInfo[#"acme1"];
localNotification.fireDate = [NSDate date];
localNotification.applicationIconBadgeNumber = 1;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
}
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// Remove the badge number
application.applicationIconBadgeNumber = 0;
}
-(void)application:(UIApplication*)application didReceiveLocalNotification:(UILocalNotification *)notification{
UIApplicationState state = [application applicationState];
if (state == UIApplicationStateActive) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Reminder"
message:notification.alertBody
delegate:self cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
// Set icon badge number to zero
application.applicationIconBadgeNumber = 0;
}
If the app is active you will be notified by application:didReceiveLocalNotification: in app delegate only. There you can display custom banner like view on the top viewcontroller presented on the view hierarchy . Just look at the whatsapp notification when the app is open
If the application is active then you will not recieve any sound, badge or alert, however the application delegate application:didReceiveLocalNotification: will be called
From apple docs
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. The UILocalNotification instance is passed into this method, and the delegate can check its properties or access any custom data from the userInfo dictionary.
If your app is currently running and active (i.e. visible), you will not see the alert message. Instead iOS will deliver the notification to your app directly through the following method
- (void)application:(UIApplication *)application
didReceiveLocalNotification:(UILocalNotification *)notification
No it will not play a sound or show a banner. However in your apps delegate , did receive notification will still be called where you can then show an alert view if you wish to notify a user.
You can however add audio manually.
- (void) application:(UIApplication *)application didReceiveLocalNotification: (UILocalNotification *)notification
{
SystemSoundID systemSoundID;
NSURL *soundURL = [[NSBundle mainBundle] URLForResource:#"blip"
withExtension:#"mp3"];
AudioServicesCreateSystemSoundID((__bridge CFURLRef)soundURL, &systemSoundID);
AudioServicesPlaySystemSound(systemSoundID);
}
Local notification in Foreground
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.
I have been searching around for a while trying to find an answer but I cant seem to find one. What I am trying to do is have my app send a local notification when the app is running in the background and when the user opens the notification it will take them to a website. I have it all set up but it keeps opening the app instead of going to the website.
My question is, is this even possible to do? And if so could you please see where i am going wrong with my code below? Thank you for your help.
CODE:
-(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, this method is called instead of applicationWillTerminate: when the user quits.
NSDate *date = [NSDate date];
NSDate *futureDate = [date dateByAddingTimeInterval:3];
notifyAlarm.fireDate = futureDate;
notifyAlarm.timeZone = [NSTimeZone defaultTimeZone];
notifyAlarm.repeatInterval = 0;
notifyAlarm.alertBody = #"Visit Our Website for more info";
[app scheduleLocalNotification:notifyAlarm];
if ( [notifyAlarm.alertBody isEqualToString:#"Visit Our Website for more info"] ) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:#"https://www.bluemoonstudios.com.au"]];
}
In Your Business Logic
-(void)scheduleNotificationForDate:(NSDate *)fireDate{
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.fireDate = fireDate;
notification.alertAction = #"View";
notification.alertBody = #"New Message Received";
notification.userInfo = #{#"SiteURLKey": #"http://www.google.com"};
[[UIApplication sharedApplication] scheduleLocalNotification:notification];
}
in your AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UILocalNotification *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
if(notification != nil){
NSDictionary *userInfo = notification.userInfo;
NSURL *siteURL = [NSURL URLWithString:[userInfo objectForKey:#"SiteURLKey"]];
[[UIApplication sharedApplication] openURL:siteURL];
}
}
-(void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification{
NSDictionary *userInfo = notification.userInfo;
NSURL *siteURL = [NSURL URLWithString:[userInfo objectForKey:#"SiteURLKey"]];
[[UIApplication sharedApplication] openURL:siteURL];
}