Calling UILocalNotification from Main.m - ios

I'm not sure if this is possible but I'm trying to fire a UILocalNotification from a function running on Main.m. So far I tried a couple of different ways but I'm a bit confused on who must present the notification because the simple way doesn't seem to work:
I call this code from a static function called by an Observer (defined in Main.m) on CTTelephonyCenter
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
if (localNotif) {
NSLog(#"Ciao");
localNotif.alertBody = [NSString stringWithFormat:
#"La telefonata é finitá!!!!!"];
localNotif.alertAction = NSLocalizedString(#"Read Message", nil);
localNotif.soundName = #"alarmsound.caf";
localNotif.applicationIconBadgeNumber = 1;
[[UIApplication sharedApplication] presentLocalNotificationNow:localNotif];
}
Now, the Log shows up but localNotif doesn't.
Is it just how I'm afraid, and I just can't do it from a static function called by Main because the window is not defined?
I know I shouldn't mess around with main.m

Try implementing:
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification;
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIApplicationDelegate_Protocol/Reference/Reference.html
in your application delegate.
If your app is open you can log things here, but notification center wont present anything. Notifications only show up in notification center if your app is in the background.

Related

UILocalNotification issue in IOS

I have used UILocalNotification in my code after getting the response from server. I'm sending multiple images to the server , when the response comes 1 it should show a local notification in an app.
I have tried some code it shows a notification in banner style but not one the app screen , when i press command+shift+H it goes to home screen of simulator and shows the notification there instead of in app screen.
How we can show same notification on the home screen of app. I have tested this on real device but its not showing there.
My Code is:
UILocalNotification* localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = res;
localNotification.alertBody = #"Image Sent";
localNotification.timeZone = [NSTimeZone defaultTimeZone];
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
if ([application respondsToSelector:#selector(registerUserNotificationSettings:)]) {
[application registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeAlert|UIUserNotificationTypeBadge|UIUserNotificationTypeSound categories:nil]];
}
It shows like this,
You need to handle it by yourself. When local notification comes, you can use UIAlertController to show the payload dictionary data associated with that local notification. Inside below method, you can do it. In notification settings, change notification style to alert from banner if needed.
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
This method is called when notification fire in foreground for iOS 10:
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler{
NSLog(#"User Info : %#",notification.request.content.userInfo);
completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge);
}
here you can handle the local notification and show the alert UI using TSMessage class https://github.com/KrauseFx/TSMessages
Local notifications and remote notifications are ways to inform users when new data becomes available for your app, even when your app is not running in the foreground. It is your responsibility to inform user when notification is arrived.
Use OTNotification for display Notification like push notifications' cube animation With covering statusBar While your app is in foreground.
You can Use Like this.
OTNotificationManager *notificationManager = [OTNotificationManager defaultManager];
OTNotificationMessage *notificationMessage = [[OTNotificationMessage alloc] init];
notificationMessage.title = [self notificationTitle];
notificationMessage.message = #"A notification. Touch me to hide me.";
[notificationManager postNotificationMessage:notificationMessage];

Repeating and canceling UILocalNotification

I want to have a UILocalNotification firing in my application every minute for a variable number of times and after that, I want to cancel it.
I'm trying to find a parameter that would enable me to do that.
1) Scheduling notification
Note the .repeatInterval property value.
UILocalNotification *reminder = UILocalNotification.new;
reminder.fireDate = fireDate;
reminder.timeZone = [NSTimeZone systemTimeZone];
reminder.alertBody = #"Your alert message";
reminder.alertAction = #"Your alert action";
reminder.soundName = UILocalNotificationDefaultSoundName;
reminder.repeatInterval = NSMinuteCalendarUnit;
[[UIApplication sharedApplication] scheduleLocalNotification:reminder];
2) Handling notification (AppDelegate)
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
// custom handling code
}
Note: in iOS 8 you have to register for local notifications for the delegate methods to be called.
3) Canceling UILocalNnotification
[[UIApplication sharedApplication] cancelLocalNotification:reminder];
4) Notification distinction
To keep track of how many times a notification has been received, you have to uniquely identify your notification(s). You can do that by making use of UILocalNotification instance .userInfo property.
Example
UILocalNotification *reminder = UILocalNotification.new;
...
reminder.userInfo = [NSDictionary dictionaryWithObject:#"custom value" forKey:#"notificationUniqueId"];
...
Then, when you receive your notification in delegate method written in 2), you can check for notification unique id that you stated in userInfo dictionary. Knowing that, you are able to keep track how many times a UILocalNotification has been fired and cancel it when appropriate.
Hope that helps!

Why is a banner not shown for my local notification in iOS 7

My iOS 7 app is generating local notifications in a method called within an NSOperationQueue block. The notifications are appearing in the Notification Center, but they are not showing a banner at the top of the screen. The notifications are being generated while the app is in the background.
I've tried everything I can think of, and done considerable Google searching, but I still can't get the banners to display.
Here is the code that builds and schedules the notification:
// In the most recent case, I have verified that
// alertText = Why not work? and alertAction = View
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.alertBody = alertText;
localNotification.alertAction = alertAction;
localNotification.alertLaunchImage = launchImage;
UIApplication *application = [UIApplication sharedApplication];
application.applicationIconBadgeNumber++;
localNotification.applicationIconBadgeNumber = application.applicationIconBadgeNumber;
[self performSelectorOnMainThread:#selector(scheduleNotification:)
withObject:localNotification waitUntilDone:NO];
}
- (void)scheduleNotification: (id)notification
{
UILocalNotification *localNotification = (UILocalNotification *)notification;
// Schedule it with the app
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
}
I have checked the notification settings for my app, and they are:
Alert Style: Banners
Badge App Icon: On
Sounds: Off
Show in Notification Center: On
Include: 5 Recent Items
Show on Lock Screen: On
The bug was actually in a different part of my code. I was generating the notification in a background thread, and the thread was canceled before the notification went out.
If your app is running you can't have this banners (unless you create your own).
A solution could be:
When the app is running, Notification are handle by
- (void)application:(UIApplication *)application
didReceiveRemoteNotification:(NSDictionary *)userInfo
Then you can use this project (that I use and which is really good) : TSMessages to create something similar as your banner.
Hope that will help...

Can UILocalNotification be used to wake up a task that is in the background

I would like to know, if it is possible to somehow "wake up" a task that is in the background, to quickly check something on the network.. I think that this could be done with UILocalNotification, however, no matter what I tried, I could not get the didReceiveLocalNotification to do ANYTHING when the app is in the background.. After starting up, I immediately close the app by pressing the Home button (there is a 10 second delay for local notification to fire). This code works PERFECTLY when the app is in the foreground, and just kind of sitting there...
In app delegate header file:
UILocalNotification *localNotif;
For testing, I set up local notification to fire quickly in the appDelegate startup.
localNotif = [[UILocalNotification alloc] init];
localNotif.fireDate = [NSDate dateWithTimeIntervalSinceNow:10]; // the date you want the notification to fire.
localNotif.timeZone = [NSTimeZone defaultTimeZone];
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
NSLog(#"setup the timer for 10 seconds");
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
UIApplicationState state = [application applicationState];
NSLog(#"getting kicked");
if (state == UIApplicationStateInactive) {
// Application was in the background when notification was delivered.
NSLog(#"INACTIVE..");
} else {
NSLog(#"ACTIVE..");
}
}
The user has a couple of choices: #1) Do they want to see a notification for your app. #2) If notifications are enabled for your app, do they want to click on your notification to launch your app. If they do accept notifications and open your notification while your app is in the background, application:didReceiveLocalNotification is called. To be clear, the user has to accept the notification (such as sliding the slider underneath the notification)... otherwise NOTHING is called.
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
NSLog(#"%#", notification);
}
If your app has been terminated application:didFinishLaunchingWithOptions: is called -
- (BOOL)application:(UIApplication *)
application didFinishLaunchingWithOptions:
(NSDictionary *)launchOptions {
UILocalNotification *theNotification =
[launchOptions
objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
NSLog(#"%#", theNotification);
return YES;
}

XCode : why launchOptions in didFinishLaunchingWithOptions always nil?

I want my app to do specific things when the app is launched by a click on a notification. I want to do these specific things when the app is already running into background BUT ALSO when the app is started FROM SCRATCH (not running into background) by a click on the notification.
When the app is started from background by a click on the notification, I get the notification via:
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
=> NO PROBLEM !
When the app is started from scratch by a click on the notification, I would like to get the notification via:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UILocalNotification *localNotif = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
}
But launchOptions is always nil !! It is nil when the app is started from scratch via a click on the app icon (normal) but also when the app is started from scratch via a click on a notification (not normal).
Anybody knows how to solve this issue ?
Thanks !!!
EDIT 1
Here is how my notifications are created (Joe question):
NSDictionary *userInfo = [NSDictionary dictionaryWithObjects:
[NSArray arrayWithObjects:notifText,latitudeString,longitudeString,nil]
forKeys:[NSArray arrayWithObjects:#"notifText",#"latitude",#"longitude", nil]];
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
localNotif.fireDate = itemDate;
localNotif.timeZone = [NSTimeZone defaultTimeZone];
localNotif.alertBody =msg;
localNotif.alertAction = #"Ok";
localNotif.soundName = UILocalNotificationDefaultSoundName;
localNotif.applicationIconBadgeNumber = 1;
localNotif.userInfo = userInfo;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
[localNotif release];
EDIT 2 (ANSWER TO MY QUESTION! :))
Here is the procedure I used to debug my app but...this procedure is wrong!!
I set up my debugger with the "Wait for MyApp.app to launch" option in the "Edit Scheme" menu
I launched my app with XCode a first time (launch from scratch) XCode displays the "Waiting for my MyApp to launch" => I CLICKED ON MY APP ICON to launch the app
The app is launched => I clicked on the home button => the notification is displayed
I clicked on the stop button in XCode to close the app I relaunched it with XCode => XCode displays again the "Waiting for my MyApp to launch" message => I CLICKED ON THE
NOTIFICATION in the status bar to launch the app
=> launchOptions is nil !
launchOptions equal to nil is due to the fact that relaunching the app with XCode (in this case with the "Waiting for my MyApp to launch" option) deletes the notifications even if it is still displayed in the status bar...
To be able to debug check what is the content of launchOptions after a relaunch of the app from scratch by a click on a notification, it seems that the only way is to display this content in a UIAlert as mentioned in answer by Tammo Freese. So, use the following to debug in this specific case:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"options" message:[launchOptions[UIApplicationLaunchOptionsLocalNotificationKey] description] delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertView show];
return YES;
}
Thanks all for your help !!!!
I could not find an error in the code you shared. Normally this should work both in the simulator, and on the device. Here is an example that worked for me: First generate a new Single View iPhone app (ARC and Storyboards on). Then change two methods in the AppDelegate as follows:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"options" message:[launchOptions[UIApplicationLaunchOptionsLocalNotificationKey] description] delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertView show];
return YES;
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
[[UIApplication sharedApplication] cancelAllLocalNotifications];
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
localNotif.fireDate = [NSDate dateWithTimeInterval:10.0 sinceDate:[NSDate date]];
localNotif.timeZone = [NSTimeZone defaultTimeZone];
localNotif.alertBody = #"Just some text";
localNotif.alertAction = #"OK";
localNotif.soundName = UILocalNotificationDefaultSoundName;
localNotif.applicationIconBadgeNumber = 1;
localNotif.userInfo = #{#"test": #YES};
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
}
Then start this app, press the home button, then stop the app. If you tap on the local notification which comes in 10 seconds after pressing the home button, you should see something like this, which shows the local notification has been passed to -application:didFinishLaunchingWithOptions::
My advice is: First get the example I posted above to work to make sure nothing has gone awry with your setup, then check what you are doing differently in your code.
Edit
This applies to Edit 2 of the question: Local notifications also seem to work for me when waiting for the app to launch (in the simulator, not on the device). Try this:
Install the sample app described above and launch it with "Wait for MyApp.app to launch" disabled.
Click on the home button, then stop the app via Xcode or via the task bar.
Enable "Wait for MyApp.app to launch".
If you now tap the notification in the notification center, it is shown in the alert view.
Dont know if this is what your looking for, but are you missing 'return YES;'?
Because i use this to perform a segue to a new view from a notification and it works fine
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UINavigationController *navigation = (UINavigationController *) self.window.rootViewController;
[navigation.visibleViewController performSegueWithIdentifier:#"Ident" sender:nil];
return YES;
}
My conclusion and suggestion if it can hep anyone, refer below
Every time you have new build to test your app, you must test the notification click actions with the notifications generated by latest app. If you keep on testing of click actions with old notifications generated by older build then It will behave unexpectedly (means somehow its able to launch the app but it will not return you any valid info in didFinishLaunchingWithOptions:)
Please forgive me, I am still new when it comes to Apple's Push Notification service, but I did some reading through their documentation and my guess is that there may be something in the creation of your local notification that is causing the problem.
I would double check how you are creating your local notification with Apple's Example as shown here in Listing 2-1 just to rule out that possibility. Since some of the code that is used for creating your local notification isn't displayed to us in this thread, it makes it difficult to assess if the instantiation of your local notification is indeed correct. It could end up being as simple as something being wrong with the fire date or something else in the notification not being set up correctly.

Resources