So my app has been around for 5 days now and iPhone 3GS users are reporting that their notifications doesn't cancel when the button is switched.
The button executes the following code:
[[UIApplication sharedApplication] cancelAllLocalNotifications];
However, this code works on iPhone 4,iPhone 4S,iPhone 5 and iPad.
Is this a known bug of the iPhone 3GS? Or does the 3GS require different code to achieve the same thing?
I'm running into this problem on iOS 8.1 on an iPhone 6+. It turns out that cancelAllLocalNotifications is not a synchronous call, so there is no guarantee that the cancelation has been completed when it returns. I've had to implement the following as a workaround
- (void) clearNotifications
{
NSLog(#"Clearing notifications");
[[UIApplication sharedApplication] cancelAllLocalNotifications];
long count;
while ((count = [[[UIApplication sharedApplication] scheduledLocalNotifications] count]) > 0) {
NSLog(#"Remaining notificaitons to cancel: %lu",(unsigned long)count);
[NSThread sleepForTimeInterval:.01f];
}
NSLog(#"Notifications cleared");
}
Don't know why but I had to cancel all notification by notifcation ID instead of CancelAll on iPhone 3GS
Related
"Attempting to schedule a local notification UIConcreteLocalNotification: with a sound but haven't received permission from the user to play sounds"
- (void)registerForRemoteNotifications
{
if ([[UIApplication sharedApplication] respondsToSelector:#selector(isRegisteredForRemoteNotifications)]) {
// iOS 8 Notifications
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeAlert|UIUserNotificationTypeSound|UIUserNotificationTypeBadge) categories:nil]];
} else{
// iOS < 8 Notifications
[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIUserNotificationTypeAlert)];
}
}
//added for ios8
- (void)successfullyRegisteredUserNotificationSettings
{
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
I followed the guide of other users in stackoverflow to use registerUserNotificationSettings for ios8. After invoking the function, I wait for the callback in AppDelegate:
- (void)application:didRegisterUserNotificationSettings:
In the function, I call my successfullyRegisteredUserNotificationSettings method above to formally register.
Even after doing this, I still get the error. Can someone tell me why? Or has anyone encountered the same issue? How can this be solved?
I am building with Xcode 5/iOS SDK 6.1. If the app runs on an iOS 7.x device it should check whether the setting "Settings -> General -> BackgroundAppRefresh" is set for the app. Since this property is only available on iOS 7 I am doing:
if([[UIApplication sharedApplication] respondsToSelector:#selector(backgroundRefreshStatus)])
{
NSInteger outcome=[[[UIApplication sharedApplication] performSelector:#selector(backgroundRefreshStatus)] integerValue];
//do something with "outcome"
}
However... the app crashes on iOS 7 at the "performSelector" line which is strange because it passes the "respondsToSelector" call?? Anyone knows why? I also tried NSSelectorFromString(#"backgroundRefreshStatus") with the same result.
You've got a lot of unnecessary code there. Unless the backgroundRefreshStatus selector exists before iOS 7 as a private API you don't need the version check.
Your use of #selector is also incorrect and you don't need to use performSelector, just call the method:
if ([[UIApplication sharedApplication] respondsToSelector:#selector(backgroundRefreshStatus)]) {
UIBackgroundRefreshStatus refreshStatus = [[UIApplication sharedApplication] backgroundRefreshStatus];
}
You are using a string as the selector. Try without the string:
UIApplication *app = [UIApplication sharedApplication];
if([app respondsToSelector:#selector(backgroundRefreshStatus)])
{
UIBackgroundRefreshStatus outcome = [app performSelector:#selector(backgroundRefreshStatus)];
// or outcome = [app backgroundRefreshStatus]
}
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 }
}
[[[UIApplication sharedApplication] keyWindow] addSubview:myView];
The above code is working fine in iPhone 5.1 simulator, but the view is not appearing in iPhone 6.0 simulator. What could be the problem?
You have to send makeKeyAndVisable to what ever window you want to add the subview to. Like so:
[[self window] makeKeyAndVisible];
[[[UIApplication sharedApplication] keyWindow] addSubview:view];
The key window is the window which will receive user interaction. You can check the apple docs here for makeKeyAndVisable.
I have a published (Cocos2d+UIKit)app in the store, which reproduces audio tracks and needs to keep playing them even if the iPhone is locked or the app is in background.
It used to work perfectly well until iOS 5.0 but since iOS 5.1 the app is restarted: sound stops, when user unlocks iPhone doesn't appear active, when opening again it shows the splash screen and initial window.
I tried to debug it but when I lock the iPhone, xCode gets paused in EAGL...
I also tried to play the tracks in a MPMoviePlayerViewController and it does the same.
Please help, I am getting many bad reviews every day due to this issue...
It is hard to tell without seeing your code, but as a wild guess, try this line:
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
Put in your first controller's viewDidLoad method. Let me know if it fixes the problem for you.
------ Update -----
An additional thing to check for 5.1 is to set
[[AVAudioSession sharedInstance] setActive: YES error: nil];
before each AVAudioPlayer play command.
This solved it for my alarm clock app which used to sound at the alarm time perfectly in 4.x and started to get muted in 5.1. I found that the putting the above line before [AVAudioPlayer play] solved the problem for me.
Think I finally solved it by adding:
- (void)applicationDidEnterBackground:(UIApplication *)application
{
[[CCDirector sharedDirector] stopAnimation];
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
[[CCDirector sharedDirector] startAnimation];
[Appirater appEnteredForeground:YES];
}
- (void)applicationWillResignActive:(UIApplication *)application
{
[[CCDirector sharedDirector] pause];
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
[[CCDirector sharedDirector] resume];
}
I am not sure why it was working fine before iOS 5.1, but that fixed it :)