Keep NSTimer running when app is in background - ios

I hope there's an expert out there who can help me with this:
I googled it for hours, but could not find any information if there is any way to keep a running NSTimer active when the app is running in the background ?
The problem scenario is I need to set a countdown timer on button click. Time left is shown (02:34:45) as title of button. how do my timer is keep on running when application enters into background or it is suspended . Please help me how i can maintain the time left for alarm, what are the values selected for alarm ( like 2 hours , 3 minutes )
Thanks for any help!

If you're using it for an alarm, your best bet is to use local notifications. That way you won't need to use any of the background processing modes.
When your app is about to enter the background (in applicationWillResignActive or applicationDidEnterBackground on your app delegate), get how much time is left on your timer. Then schedule a local notification for that far in the future:
NSTimeInterval timeUntilNotification = ...
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
localNotif.fireDate = [[NSDate date] dateByAddingTimeInterval:secondsUntilNotification];
localNotif.soundName = UILocalNotificationDefaultSoundName;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotif];
When your app becomes active again, make sure to cancel all your notifications with cancelAllLocalNotifications.

Related

Increase loudness of app output

Let assume user set loudness on its iphone to 5/10 value, i want to increase volume that my app outcome from 0% to 100%, where 100% is 5/10 (value that is set by user). I want that action to be made slowly increasing, for example for 20 seconds.
If i understand correct, app can't exceed value of maximum volume output that is set by user.
Unfortunately i couldn't find a way to do that. Where should i begin to achieve that task?
I want to make an alarm.
Right now i use following logic to send push notification, that "wake up" user.
- (void)sendLocalPushForAlarm {
if (IS_OS_8_OR_LATER) {
[self registerForLocalNotification];
}
UILocalNotification *notification = [[UILocalNotification alloc] init];
[notification setAlertBody:NSLocalizedString(#"WAKE_UP", nil)];
if (IS_OS_8_OR_LATER) {
[notification setCategory:NotificationCategoryIdent];
}
[[UIApplication sharedApplication] presentLocalNotificationNow:notification];
}
the only way you could maniple the loudness is when your app is running in the foreground (or rather: if you MANUALLY play the right sound using e.g. AVPlayer. this is normally not possible in the bg, so I simplified it to 'foreground only')
apart from that there is no way.
(ugly) workaround to come close maybe: have multiple notifications with multiple sound files that are recorded at a different loudness level
==> my vote would be no way

remove/update notification from lock screen

I use UILocalNotification to show alerts.
I need to show two alerts 2 hours apart.
Right now, my code displays two different notifications on lock screen.
Assume, alerts/notifs were not touched by user during this period.
Is it possible for me to
Either remove the first shown notification from lock screen
Or update the first notification with the contents of second alert/notifcation.
To my understanding, you cannot modify a UILocalNotification once it has been scheduled.
To dismiss an already fired UILocalNotification, try calling the [[UIApplication sharedApplication] cancelAllLocalNotifications];
and then re-add those that were not yet fired.

iOS 8 custom alarm using uilocalnotification and playing sound in background when phone is on silent

I am trying to build a custom alarm application. But the challenge I am facing is getting the sound played while app is in the background.
First method, UILocalNotification,
According to the Apple programming guidelines, the right way to make an alarm is
- (void)scheduleAlarmForDate:(NSDate*)theDate
{
UIApplication* app = [UIApplication sharedApplication];
NSArray* oldNotifications = [app scheduledLocalNotifications];
// Clear out the old notification before scheduling a new one.
if ([oldNotifications count] > 0)
[app cancelAllLocalNotifications];
// Create a new notification.
UILocalNotification* alarm = [[UILocalNotification alloc] init];
if (alarm)
{
alarm.fireDate = theDate;
alarm.timeZone = [NSTimeZone defaultTimeZone];
alarm.repeatInterval = 0;
alarm.soundName = #"alarmsound.caf";
alarm.alertBody = #"Time to wake up!";
[app scheduleLocalNotification:alarm];
}
}
Problem is,
if the user has the phone on silent, the notification sound will only be a small vibrate that doesn't suffice for a alarm.
Idealy, I want a alarm that will go off no matter the phone is on silent or normal to wake up the user.
Second way I can think of, AVAudioSession
But when the region is near or alarm trigger comes in, audioSession cannot be initiated in the background so any audioPlayer.play() methods won't do anything.
Besides the above 2 methods that both don't work, I can't seem to find any other ways to tackle the problem at hand.
I am trying to make an App which is a location based alarm.
I can set a region and custom sound for 30 seconds on my UILocalNotification but the sound won't play if phone is silent.
I can have a locationManager monitoring my region but I can't play a sound after I get notified from the background.
I've downloaded many Apps that are capable of doing this so I know there must be way of achieving it. However, after multiple tries in various angles, I can't seem to find any good solutions. If anyone had experience with making a custom alarm, please share some tips and pointers if you can.
Thank you.
Since my reputation is not enough to comment everywhere, I would write it here as an answer. Sorry about this.
I'm also suffering with the same problem. Though I cannot give you a solution, there might be some hints to you. To me, I think it might be impossible to achieve.
I have double checked two alarm application I use: Sleep Cycle and UNIQLO Wake Up. And I found out that these two applications asked you to keep it always running on the foreground to make sure that the alarm clock will work. Especially UNIQLO Wake Up, it will show you an alert when you save the alarm clock, telling you that press Home button may cause the alarm clock not working.
There is a post asking about similar question, and the author provide some names of the applications: How do I start playing audio when in silent mode locked in iOS 6. I checked the application called WaveAlarm. Similarly, if the cellphone is in mute mode and you put it into background, only UILocalNotification will work. This means, no sound will be played in this situation. If your cellphone is still in the mute mode, but you keep the application in the foreground, it will play a sound. The volume of the sound depends on the volume you set for video playing.
So to me, I think it might impossible to play alarm sound when you put the application into background and set the cellphone into mute mode. I guess the most possible way to achieve this is to ask users to keep it in foreground, and play a media with the alarm sound.
I'll try to achieve this function in these two days. If I have some other understandings, I'll edit this post here.

iBeacon monitoring implementation ios7.1

I’ve a problem about iBeacon monitoring implementation. I fire a local notification when locationManager:didDetermineState:forRegion: method is called. When application goes in background I don’t get any local notification at all but they came all at once when I active the screen pushing the home button. According to time I leave sleep the device I can get up to tens notification always when I wake it up. How is that possible? Anyone had the same problem?
I use iPhone 5S and 5C with iOS 7.1. The local notification is set in this way:
- (void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region{
UILocalNotification *localNot = [[UILocalNotification alloc] init];
localNot.alertBody = [NSString stringWithFormat:#"Region state %d determined", state];
localNot.alertAction = #"Go for it!";
localNot.soundName = UILocalNotificationDefaultSoundName;
localNot.fireDate = nil;
[[UIApplication sharedApplication] presentLocalNotificationNow:localNot];
}
I suspect that you are not actually doing any background detections at all, and the reason you see the notifications when you hit the home button is because you have the notifyEntryStateOnDisplay flag set, which causes you to get an extra callback to didDetermineState: forRegion: whenever the screen comes on, for every region you are monitoring with the flag set.
Why do you not get callbacks in the background? You may need to wait up to 15 minutes to detect an iBeacon in the background, even on iOS 7.1. See here.

How to change view controller everyday at specific time in iOS

I have a case where a user needs to submit a form everyday before 8am.
When they submit, a confirmation view is overlaid to show the user they have submitted as well as stop them from submitting again.
After 8am, I want to clear the form and have the form view available again by hiding the overlaid view. I want to do this at one point in time at 8am if possible.
I was thinking about accomplishing this with NSTimer. Can I set a timer that will run at 8am that will clear the form and remove the overlay view?
Is there a better way to handle this scenario?
You could use a local push notification. Official doc here
https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Introduction.html
Something like that:
UILocalNotification *localNotification = [[UILocalNotification alloc] init];
localNotification.fireDate = [NSDate date]; // Replace me with your "event" date
localNotification.timeZone = [NSTimeZone localTimeZone];
localNotification.repeatInterval = kCFCalendarUnitDay;
[[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
then you can "catch" the notification as the doc says
If your app is frontmost, the application:didReceiveRemoteNotification: or application:didReceiveLocalNotification:method is called on its app delegate If your app is not frontmost or not running you handle the notifications by checking the options dictionary passed to the application:didFinishLaunchingWithOptions: of your app delegate for either the UIApplicationLaunchOptionsLocalNotificationKey or UIApplicationLaunchOptionsRemoteNotificationKey key.
You can't use just a NSTimer, because it will not run when your app is closed, however another solution that involves NSTimer is to create a NSTimer for the event date, and then observe UIApplicationDidEnterBackgroundNotification, here if the timer is running, you'll stop the timer, persisting the timer.fireDate (you can save it in NSUserDefault for example), finally observing UIApplicationDidBecomeActiveNotification, you can recreate the timer (substracting the current time with the value that you saved previously) or just fire the action if the event time already passed on.
If you don't want to use a UILocalNotification you can dynamically define your initial view controller (VC) by:
Programmatically loading the VC in didFinishLoadingWithOptions: in AppDelegate
Or subclass your UINavigationController and set your rootController dynamically

Resources