iOS UILocalNotification not being displayed while app in background - objective-c

FIXED — Ok, found what it was, there was an errant [[UIApplication sharedApplication] cancelAllLocalNotifications]; being fired when I wasn't expecting it.
Well there's your problem.
Thanks for the help everyone, sorry to have it turn out to just be dumb coder syndrome.
I've built out my local notification like so:
- (void)scheduleNotification {
[[UIApplication sharedApplication] cancelAllLocalNotifications];
Class cls = NSClassFromString(#"UILocalNotification");
if (cls != nil) {
UILocalNotification *notif = [[cls alloc] init];
NSLog(#"%#", [NSDate date]);
notif.fireDate = [NSDate dateWithTimeIntervalSinceNow:10];
notif.alertBody = NSLocalizedString(#"Hello.", nil);
[[UIApplication sharedApplication] scheduleLocalNotification:notif];
NSLog(#"Notification scheduled at %#", notif.fireDate);
[notif release];
}
}
As expected my debug log outputs the correct fireDate 10 seconds in the future. If I don't leave my app I get a successful application:didReceiveLocalNotification: callback.
The hiccup here is if I push the button to schedule this notification and hit the home button to put it in the background. If I do this, the notification never fires and I never get an alert view from the OS.
Did I miss something obvious here? I've looked up and down here and the Apple docs and feel I've missed something obvious.
Any help would be greatly appreciated. Thanks.

See the example in Apple's docs:
http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/IPhoneOSClientImp/IPhoneOSClientImp.html#//apple_ref/doc/uid/TP40008194-CH103-SW1
Could it be that not setting timeZone to [NSTimeZone defaultTimeZone] is causing the problem? GMT is assumed if timeZone isn't set (nil default).

Have you tried wrapping the code in a background task?

Ok, found what it was, there was an errant [[UIApplication sharedApplication] cancelAllLocalNotifications]; being sent when entering the background.

Related

Stopping ios 7 remote notification sound

In iOS 7, when a user swipes one of my notifications from the lockscreen and is taken to my app, the notification sound keeps playing (unlike iOS 6). Is there any way to programmatically stop that sound when my app launches in iOS 7?
NOTE: see the accepted answer for a shoddy workaround.
I'm pretty sure this is a bug on Apple's end, see devforums.apple.com/message/888091 (thanks Gui13). File a duplicate bug report to get Apple to pay attention to it, as that is how Apple assigns priority to bugs. In the meantime, the following will work but will also clear all of your notifications in the notification center, which of course is a shoddy workaround, but in my case is worth it until this gets fixed:
[[UIApplication sharedApplication] setApplicationIconBadgeNumber: 1];
[[UIApplication sharedApplication] setApplicationIconBadgeNumber: 0];
it doesn't help by using
[[UIApplication sharedApplication] setApplicationIconBadgeNumber: 1];
[[UIApplication sharedApplication] setApplicationIconBadgeNumber: 0];
after entering the app by clicking the notification.
I have solved this problem by sending another empty notification when dealing with the notification with sound:
if (notification.soundName != nil) {
if (IS_IOS7) {
UILocalNotification *emptyNotification = [[UILocalNotification alloc] init];
emptyNotification.timeZone = [NSTimeZone defaultTimeZone];
emptyNotification.fireDate = [NSDate date];
emptyNotification.alertBody = #"";
[[UIApplication sharedApplication] scheduleLocalNotification:emptyNotification];
}
}
For iOS 7, the accepted answer may be the only viable option. For developers who have come here that can support a minimum of iOS 10, this works.
You can remove all notifications from Notification Center by calling
UNUserNotificationCenter.current().removeAllDeliveredNotifications()
This has a very similar affect as the accepted answer: the audio stops playing and all the notifications are removed from Notification Center.
An improved solution is to use
UNUserNotificationCenter.current().removeDeliveredNotifications(withIdentifiers: [String])
This stops the audio for only the given notifications, and removes them from Notification Center.
To get the ids for all the delivered notifications, use
UNUserNotificationCenter.current().getDeliveredNotifications { notifications in
let ids = notifications.map { $0.request.identifier }
}

UILocalNotification sometimes don't notify me

in my app i schedule some UILocalNotification every time the app is opened, but happen that sometimes the uilocalnotification is not fired and don't notify me,and when happen they don't fired anymore, to fix it i have to reinstall the app on the iPhone, so i'm explain me well, there is a period of time that the notification work and then one day the dont' work anymore and to fix it i have to reinstall it again, so to investigate i have create this method that it's called when the app did become active:
-(void)checkNotification {
for (UILocalNotification *someNotification in [[UIApplication sharedApplication] scheduledLocalNotifications]) {
NSLog(#"%#",someNotification.alertBody);
NSLog(#"%#",someNotification.fireDate);
}
}
and i see that all notification are scheduled and also the date, this is an example:
2012-11-25 18:36:36.532 TestApp[672:907] This is a notification.
2012-11-25 18:36:37.482 TestApp[672:907] 2012-11-27 10:00:00 +0000
so i can't understand why i don't receive notification...any help?
Edit:
i create a notification in this way:
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = myNewDate;
localNotification.timeZone = [NSTimeZone defaultTimeZone];
localNotification.alertBody = #"This is a notification.";
localNotification.soundName = #"smallBell.mp3";
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
You may or may not get the alert message. It depends on whether your app is running and in which state, e.g. active in the foreground, active in the background, or not running at all.
Please see this article for clarification - http://www.thekspace.com/home/component/content/article/62-uilocalnotification-demystified.html

MFMailComposeViewController dismisses right away

The situation is the MFMailComposeViewController was going to be presented. I saw it was presented half-way done, but then it got dismissed.
This is the error:
_serviceViewControllerReady:error: Error Domain=_UIViewServiceInterfaceErrorDomain Code=3 "The operation couldn’t be completed. (_UIViewServiceInterfaceErrorDomain error 3.)"
This is my source code to present the MFMailComposeViewController:
-(void) MailExecute {
if ([MFMailComposeViewController canSendMail])
{
MFMailComposeViewController *mailViewController = [[MFMailComposeViewController alloc] init];
mailViewController.mailComposeDelegate = self;
[mailViewController setSubject:NSLocalizedString(#"Check this new look", #"")];
[mailViewController setMessageBody: #"my new look" isHTML:YES];
[self presentModalViewController:mailViewController animated:YES];
[mailViewController release];
}
else
{
UIAlertView *alertInternal = [[UIAlertView alloc]
initWithTitle: NSLocalizedString(#"Notification", #"")
message: NSLocalizedString(#"You have not configured your e-mail client.", #"")
delegate: nil
cancelButtonTitle:NSLocalizedString(#"OK", #"")
otherButtonTitles:nil];
[alertInternal show];
[alertInternal release];
}
}
The weird point is that sometimes it happens, sometimes it doesn't.
Please help me on this! I spend almost 1 working day to resolve this but no succeed.
This problem can occur when displaying a remote view controller -- a view controller run in another process -- as indicated by the UIViewService reference in the error message.
I've had this problem when displaying an SKStoreProductViewController, which is also a remote view controller. I'm not sure what the root cause is; the only thing that seemed to trigger it for me was presenting the view controller repeatedly.
For the SKStoreProductViewController I was able to check for this error in the completion block of the loadProductWithParameters:completionBlock: method. Does the MFMailComposeViewControllerDelegate give you a callback with an error about this? It may be that all you can do is listen for this error and show an error message to the user.
We should both probably file an apple radar about this.
Your code looks correct, and as stated the error message strongly suggests this has something to do with UIView proper (not MFMail specifically). The problem almost surely lies somewhere elsewhere within your code, and might be challenging to troubleshoot.
Some things to look for:
Other animations or view controller transitions/dismissals happening simultaneously or incorrectly (possibly like this)
Release/retain issues, of course
If none of that seems like the fix, try commenting-out everything else happening in the view controller that calls this method and see if it works then.
If you still can't get it working, present the simplest version you can of failing code so we can troubleshoot further. :)
Do you have anything in your viewDidDisappear: or viewWillDisappear methods that would dismiss a view controller?
If not, can you post more of your code for the ViewController that presents the MFMailComposeViewController?
I know this is the late reply, but may be help some other.
Just now face the same problem, By resetting the simulator work fine for me for this same issue. Let me know if this helps.
After I stored the MFMailComposeViewController in a strong property of my class instead of a local variable I could not reproduce the self-dismissing behaviour any more.
The issue for me was an incorrect argument when calling the attachment function. If you are having this issue with an email attachment I suggest following the solution found in this thread, as follows:
NSString *path = [self getDatabaseFilePath];
NSData *myData = [NSData dataWithContentsOfFile:path];
[picker addAttachmentData:myData mimeType:#"application/x-sqlite3" fileName:[path lastPathComponent]];
MFMailComposeViewController *mailComposer = [[MFMailComposeViewController alloc]init];
if ([MFMailComposeViewController canSendMail])
{
mailComposer.mailComposeDelegate = self;
[mailComposer setToRecipients:[NSArray arrayWithObject:#"support#kapsie.com"] ];
[mailComposer setSubject:#"Kapsie App Contact Support"];
[mailComposer setMessageBody:#"Type Your Feedback message here" isHTML:NO];
[self presentViewController:mailComposer animated:YES completion:nil];
}
Use above code and check it on device.
Use of modelViewController is deprecated in iOS 6 ,
use
[self presentViewController:mailView animated:YES completion:nil];
I face the same problem and the solution was:
I delete the overall application appearence related code like
[[UILabel appearance]setText:#""]
and replace with the code
[[UILabel appearanceWhenContainedIn:[self class], nil] setText:#""];
Now it is working fine so be carefull on overall application appearence changes: it might be navigationbar appearance, so and so

Custom iOS UILocalNotification sound does not play (possibly related to Xcode update)

I'm trying to get a custom sound working on a UILocalNotification, and I'm just getting no sound at all. If I use UILocalNotificationDefaultSoundName, I indeed get the default sound, but when the custom sound is specified, there is no sound, just the message. The sound is less than 30 seconds and it's in the right format, as far as I can tell. Here's a screenshot of the file info:
I've inspected the .app directory in XCode's DerivedData directory, and the alarm.caf file is at the root of the app, which I believe means it's in the bundle (right?).
I'm pretty sure this was working a while ago, and I've since upgraded Xcode. Maybe that is a hint?
I've also tried deleting/reinstalling/rebooting as mentioned in other answers. As you can see, I'm calling cancelAllLocalNotifications first.
Does anyone have any idea what could be wrong?
[[UIApplication sharedApplication] cancelAllLocalNotifications];
NSLog(#"installing alarm");
[arguments pop]; // name
[arguments pop]; // title
alarm.alertBody = [arguments pop];
alarm.fireDate = [[NSDate date] addTimeInterval:[[arguments pop] intValue]/1000];
//alarm.soundName = UILocalNotificationDefaultSoundName;
alarm.soundName = #"alarm.caf";
[[UIApplication sharedApplication] scheduleLocalNotification:alarm];
Your code seems to be good.
Try to clean your project, uninstall your app from your device/simulator, then re-install it. It could help maybe :)
I don't know the reason (and I didn't read documentation too), I just turned on the action property notification setHasAction:YES and the sound began to play.
please make sure that the iPhone is not in silent mode( because your code seems to be good )
just check the button on the side of your iPhone
Ok, so here's what happened. I forgot how the app handles the notification itself if it is still running. My code was only displaying a UIAlertView and not playing the sound. I'm not sure why it worked with the default sound. In any case, I added code like this to my AppDelegate:
- (void)application:(UIApplication *)application
didReceiveLocalNotification:(UILocalNotification *)notification
{
NSLog(#"didReceiveLocalNotification");
if (application.applicationState == UIApplicationStateActive) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"MarkMyTime"
message:notification.alertBody
delegate:self cancelButtonTitle:#"OK"
otherButtonTitles:nil];
NSString *soundFilePath = [[NSBundle mainBundle]
pathForResource:notification.soundName ofType:nil];
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath: soundFilePath];
AVAudioPlayer *player = [[AVAudioPlayer alloc] initWithContentsOfURL: fileURL error: nil];
[fileURL release];
player.delegate = self;
[player prepareToPlay];
[player play];
[alertView show];
if (alertView) {
[alertView release];
}
}
}
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
NSLog(#"Releasing player");
[player release];
}
This will show a UIAlertView and play the sound on the notification object. You also need to add the AVAudioPlayerDelegate interface to the AppDelegate to be able to assign the delegat to the player. I think if you are using ARC, this code could be simplified a bit.
#interface AppDelegate : PhoneGapDelegate <AVAudioPlayerDelegate> {
I'm not sure if this is the best approach, so feel free to chime in with any improvements.
Maybe you do not add the sound file (*.caf) in Xcode project: Build Phases/Copy Bundle Resources.
Your code is good, but check your iPhone setting
setting -> Notification center -> Your App -> Sound - > "On"
the sound should be "On".
So, to enable this, checked Inter App Audio at Capabilities in Targets of the application and it was Off Capabilities in Inter-app audio
change this to On.
Then local notification sound is working.

Is it possible to display only badge and sound in the push notification in iphone

I am using push notification to inform the user that they have a new message. Is it possible to show only the badge and sound when the new message comes without the alert message. Will apple allow to use these kind of notification. If so can any one kind me how to proceed.
Thanks in advance
Sure you can show only badge and sound.
For this what you have to do is:-
where you have set your notification type write:-
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeSound|UIRemoteNotificationTypeBadge)];
do not add alert notification.
Give the notification only with sound and batch details dont give the alert notification.
-(void) scheduleNotificationForDate: (NSDate*)date {
[[UIApplication sharedApplication] cancelAllLocalNotifications];
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = date;
NSLog(#"Notification will be shown on: %#",localNotification.fireDate);
localNotification.timeZone = [NSTimeZone defaultTimeZone];
localNotification.soundName = UILocalNotificationDefaultSoundName;
localNotification.applicationIconBadgeNumber = 1;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
}