I am creating a voip application for iPhone and iPad family in which I have done following things :
Added the UIBackgroundModes key in the plist file with values 'audio' and 'voip'.
Create NSInputStream and NSOutputStream with tag NSStreamNetworkServiceTypeVoIP and scheduled them in runloop of another thread(not main thread).
Created a background task in applicationDidEnterBackground.
Added setKeepAliveTimeout handler (timeout value 600 sec).
Application relaunches when code in handler of setKeepAliveTimeout is called.
Application relaunches if I dont put setKeepAliveTimeout handler ,but tries to send any signal to app after suspension(10 mins in background is completed).
I have tried almost everything that came in my mind, Need pointers towards the solution Thanks in advance,
It is the duty of the setKeepAliveTimeout handler to care about the connection. Thus, you should use an alive interval that is shorter than the timeout time of your connection.
Related
Well I am having two issues that i can't get to work, related to audio and calls.
The first one is to play a sound during a phone call. I don't want to play continuous music or stream anything, it is just a simple and short sound that the user will hear at one time during his call.
I have read some posts claiming that this is possible, and I even have an application that does so, but I can't get it to work. My app identifies the call using CTCallCenter and print the logs but never plays the sound or plays it after the app comes to foreground again. I have the .plist property of required background mode App plays audio.
The second issue, is to play the sound after some elapsed time. NSTimers doesn't work when on background mode, nor NSThread sleep on my background process or NSOperation. So how could I play this sound after say 10 seconds of the call?
Also, this behavior has to work also when the application is already on background mode. With CTCallCenter I am only getting the event when the application is interrupted from use, but I don't see any logs when i send the app to background and then begin/receive a call
.
If anyone could point me to the right direction I'll be really grateful.
I havent done this, but NSLocalNotifcation, schedule a notification to play when you app get the call to move into the background. I would expect this to work. Interested to find out if it does.
I have an app, that will keep track of everything the user do in the iPod app. To do this, I added few observers to NSNotificationCenter, like MPMusicPlayerControllerNowPlayingItemDidChangeNotification. But my problem is, I only get those notifications when my app is in the foreground, if its in the background, the system add the notification to a queue, and then the next time my app becomes active it delivers it to me. I have no interest in this queue, since I want to receive real-time notifications.
Is there any way for me to get those notifications even if my app is in suspended state? I want to run just 3 lines of code everytime I get this NowPlayingItemDidChange notifications for example.
Here is where I add the observer.
MPMusicPlayerController *iPodMediaPlayer = [MPMusicPlayerController iPodMusicPlayer];
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter addObserver: self selector: #selector(handle_NowPlayingItemChanged:) name:MPMusicPlayerControllerNowPlayingItemDidChangeNotification
object:iPodMediaPlayer];
[iPodMediaPlayer beginGeneratingPlaybackNotifications];
Also, if I add another kind of object to the observer instead of iPodMediaPlayer, the observer won't call the method.
Thanks a lot,
Abras
iOS applications are suspended when they are not in the foreground. There are three exceptions to this rule. You can have code execute in the background if your application is
a) Playing audio. This means the application itself is actually generating audio. My understanding is that the MPMediaPlayerController iPodMusicPlayer object only controls the playback of the external iPod process, rather than playing audio from the app itself. Perhaps you could have some success if you called applicationMusicPlayer instead of iPodMusicPlayer and set the appropriate background flags in your applications Info.plist. This seems like the most legitimate way to get your application to work, but you wouldn't be able to control iPod playback from the iPod app, only your app and the system audio controls.
b) Get your app to monitor the location. If the app is using the GPS it can continue to execute in the background. Downside to this is that the GPS will drain battery, and users might be creeped out that you're requesting their location.
c) Ask UIApplication for extra time. If you use UIApplication's beginBackgroundTask method, your application will continue to run for a finite amount of time in the background. If your users are going to come into your application once every ten minutes or so, this could work as well.
Hope that helps.
Multitasking in iOS is currently a very restricted one. You may start a background task using beginBackgroundTaskWithExpirationHandler: method (of an UIApplication object), but it is intended to finish a finite-length task before going suspended. All background tasks may expire (and get terminated) before it finishes its job. You can check how much longer your application can run by checking backgroundTimeRemaining property of the application object.
As I explained here iOS receive Media Player Notifications when app is in background, there seems no way to get notifications from iPodMusicPlayer.
About Omar Raul Qazi answer:
a) i tried and I had no success. The music kept going down when pressing home button. I think this background flag only works for normal AudioSessions and not for MPMusicPlayer...
b) I am not sure this would work and I don't think Apple would like it when looking for approval
c) You can run in background only synchronous task. You cannot wait there for a notification. Am I wrong?
I am developing an iphone app which uses background audio (on an infinite loop) to continue playing after the app has entered the background.
My problem is I want to implement a "sleep timer" which stops playback after a specified period of time.
Is this possible? I have spent an hour looking for a method to do this with no avail.
EDIT: My current thought is to use a lower level API, the Audio Queue Services, and manually re-fill the queue with another instance of the loop during the AudioQueueOutputCallback. If the timer has expired I do not fill the loop. I'm assuming this should work since the documentation says audio callbacks are still fired when an app is playing multitasking background audio. Can anyone think of a better way or a reason why this wouldn't work?
While you queue sound data on the background your app remains fully functional and running as if it was in the foreground (well almost), so yes, you should just write a timer that stops the playback at a given time and it will be fired as expected.
Now to the second question: once you stop queueing things up, your app will be "frozen" until the user manually brings it to the foreground... So what you should do is start queueing audio data from the second file before the first one is done playing, and if you DO need to pause or stop, maybe a solution is to play 0 bytes (silence)?
I'm not actually sure this would be allowed in the App Store. An app is not allowed to execute at all in the background, with the exception of VoIP apps and push notifications.
I have to keep a NSThread or NSTimer when my iPhone application goes into background mode. Is it possible ? I have enabled the background modes in info.plist and opened readstream and writestream as follows ...(I am using UDP)
CFReadStreamSetProperty(readStream, kCFStreamNetworkServiceType,kCFStreamNetworkServiceTypeVoIP);
CFWriteStreamSetProperty(writeStream, kCFStreamNetworkServiceType, kCFStreamNetworkServiceTypeVoIP);
But when my application goes to background and locked state, NSThread or NSTimer is not calling . So please suggest me how to achieve background threading in iPhone background locked state ?
I wonder this too.
I want to update my CLLocation (current location) object every five minutes. The only way that i know of is to do this with NSTimer.
What is your advice if this isn't possible?
For some applications(audio, location, voip) Apple allows background execution on supported devices.
Support for some types of background execution must be declared in advance by the application that uses them. An application declares this support by including the UIBackgroundModes key in its Info.plist file. Its value is an array that contains one or more strings with the following values:
audio
location
voip
Instead of NSTimer use UILocalNotification which can fire notifications both when the app is in the background and in the foreground.
I have created an app that uses NSTimer, which gets triggered each second.
My problem is that if the Iphone is in sleep mode i get a delay for 10 to 15
minutes before the event is triggered. I have stackoverflowed and googled this
and the reason for this seems to be that the phone stops listening for certain
events when in sleep mode.
Some people have solved this issue by playing a mute sound, not allowing the
phone to sleep.
What could be the reason for the delay?
The mute sound solution seems to be a very "dirty" one. Is there some other way to solve this?
If I use the mute sound solution will it the pass the apple review?
Code:
timer = [NSTimer timerWithTimeInterval:1.0f target:self selector:#selector(goAction)userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
-(void)goAction {
// Here i check for some dates and then call the activateBeepAlarmView
}
Well since no one has answered my three questions I will have to answer them:
1. What could be the reason for the delay?
I will have to quote Ben S:
Once applicationWillResignActive gets called on your application you simply stop receiving events:
The delegate can implement this method to make adjustments when the application transitions from an active state to an inactive state. When an application is inactive, it is executing but is not dispatching incoming events. This occurs when an overlay window pops up or when the device is locked.
The point of sleep mode is to save energy. To do so, the device stops listening for events like the ones you're asking for. NSTimer events will still fire since they don't require expensive (battery-wise) hardware monitoring. Also, alarms are implemented using NSTimer, so they need to be able to function even when in sleep. Otherwise, people might not wake up and blame their iPhone.
2. The mute sound solution seems to be a very "dirty" one. Is there some other way to solve this?
No, currently I haven't found another solution, please feel free to correct me if I'm wrong.
Check out this blog post how to do it.
3. If I use the mute sound solution will it the pass the apple review?
Yes
When the iPhone goes to sleep, so does your app and the runloop that runs the NSTimer.
You seem to think that an NSTimer is some sort of hardware based timer. It is not. It operates completely within the software of the app that launches it. I don't know what is waking your app up but it is definitely not the NSTimer.
In short, what you want to do is impossible. You can't sleep the phone and then have an app still active and running. The mute sound technique is just a kludge to keep the phone awake and the app running.
If you need the phone to stay awake, you need to set the application's idleTimerDisabled to YES. This will prevent the phone from sleeping and the app can remain active. But once you let the phone sleep, it cannot be awaken from app code. Only the hardware can do that in response to an alarm or an incoming message.
What happens in your app when the NSTimer is triggered each second? Please provide code showing the creation of the timer as well as the code for the selector that is called when the timer completes.
Also what do you mean by a "delay for 10 to 15 minutes"? Is the delay always that long or is that how long you wait to awaken the iPhone and then the event is triggered?
Depending on what you need to do every second you can handle this situation in different ways. Please respond and we'll try to work our way through this.
Bart
#Jakob,
This is impossible with the "Official SDK". If you're developing apps for jail broken phone, then you can use IOKit framework for this. For more info please refer this.