1

I want to play an "audio" after 5 seconds when my app goes in background mode. The NSTimer triggered correctly. I am getting the NSLog(@"repeat"); after 5 seconds. But, some how the audio isn't playing. I enable Background Modes in my target. I try with many other solution, found here in stackoverflow, but no luck. Can any one provide me the right solution.

In my appdelegate.h file:

#import <UIKit/UIKit.h>
#import <AVFoundation/AVFoundation.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate>
{
    NSTimer* timer;
}

@property (strong, nonatomic) UIWindow *window;

@property (nonatomic, strong) NSString *musicName;
@property (nonatomic, strong) AVAudioPlayer *audioPlayer;

In my appdelegate.m file:

#import "AppDelegate.h"

@interface AppDelegate ()

@end

@implementation AppDelegate

@synthesize
musicName,
audioPlayer;

-(void) playAlarmSound
{
    musicName = @"note3BreakOf.mp3";
    // Construct URL to sound file
    NSString *path = [NSString stringWithFormat:@"%@/%@", [[NSBundle mainBundle] resourcePath], musicName];
    NSURL *soundUrl = [NSURL fileURLWithPath:path];

    // Create audio player object and initialize with URL to sound
    audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:soundUrl error:nil];
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    [self playAlarmSound];
    return YES;
}

-(void)methodRunAfterBackground
{
    [audioPlayer play];
    [timer invalidate];
    NSLog(@"repeat");
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    UIApplication *app = [UIApplication sharedApplication];

    //create new uiBackgroundTask
    __block UIBackgroundTaskIdentifier bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
        [app endBackgroundTask:bgTask];
        bgTask = UIBackgroundTaskInvalid;
    }];

    //and create new timer with async call:
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        //run function methodRunAfterBackground
        timer = [NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(methodRunAfterBackground) userInfo:nil repeats:NO];
        [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
        [[NSRunLoop currentRunLoop] run];
    });
}
John Saunders
  • 160,644
  • 26
  • 247
  • 397
Tulon
  • 4,011
  • 6
  • 36
  • 56
  • http://stackoverflow.com/questions/27733310/swift-playing-fine-mp3-file-on-simulator-but-no-volume-while-playing-on-device/27733443#27733443 – David Karlsson Jan 12 '15 at 12:22
  • @ David Karlsson, Thanks for your comment. But I'm afraid the question and answer is in SWIFT. – Tulon Jan 12 '15 at 12:23
  • did you add "app plays audio" to your plist? – David Karlsson Jan 12 '15 at 12:26
  • Yes, I did. When I enable `Background Modes` in my target, then it gives me option, where I tick the `Audio & AirPlay` in the list. And then the `App plays audio` automatically added in `Required background modes` in plist. – Tulon Jan 12 '15 at 12:29
  • Unlike forum sites, we don't use "Thanks", or "Any help appreciated", or signatures on [so]. See "[Should 'Hi', 'thanks,' taglines, and salutations be removed from posts?](http://meta.stackexchange.com/questions/2950/should-hi-thanks-taglines-and-salutations-be-removed-from-posts). BTW, it's "Thanks in advance", not "Thanks in advanced". – John Saunders Jan 17 '15 at 05:54
  • OK, I got it. English isn't my native language. But I'll follow the structure, that's for sure. – Tulon Jan 17 '15 at 16:48

3 Answers3

1

You need to add "playsAudio" to your plist and set

  • AVAudioSession sharedInstance category to: AVAudioSessionCategoryPlayback
  • AVAudioSession sharedInstance setActive: YES
  • UIApplication sharedApplication beginReceivingRemoteControlEvents

Seems some of that might be deprecated, check here

In Objective-C:

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
[[AVAudioSession sharedInstance] setActive: YES error: nil];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
Community
  • 1
  • 1
David Karlsson
  • 9,396
  • 9
  • 58
  • 103
  • I appreciate for your solution. But it is not working. I put it in `applicationDidEnterBackground`, `didFinishLaunchingWithOptions`, beginning of the `methodRunAfterBackground` method. But it is not playing the music after goes back in Background mode. :( – Tulon Jan 14 '15 at 10:09
  • I check with out `applicationDidEnterBackground`, and play the music in `didFinishLaunchingWithOptions`. Then the music playing well after starting the apps. So, the audio code is perfect. But some how the Background mode is not playing the music. I `NSLog` something in `applicationDidEnterBackground`. Though, It's print the log. – Tulon Jan 14 '15 at 10:19
1

I want to play an "audio" after 5 seconds when my app goes in background mode

Well, you can't. If your app is not actively playing audio at the time it goes into the background, then when it goes into the background, it is suspended - regardless of your background settings. Your timer stops and the app sleeps.

(Many people solve this by playing a "silent" track as the app goes into the background, so that the app is playing something at that time, and can run in the background.)

matt
  • 515,959
  • 87
  • 875
  • 1,141
  • You don't have to be actively _playing_ audio, you just need to have an active AVAudioSession (with category playback or playAndRecord). – John Scalo Aug 26 '20 at 16:06
  • @JohnScalo Not necessarily. Your session might be active at the time it goes into the background and you still might not be able to start playing in the background. – matt Aug 26 '20 at 16:19
  • that hasn't been my experience and Apple explicitly states “Your app must have an active audio session before entering the background.” https://developer.apple.com/library/archive/qa/qa1668/_index.html – John Scalo Aug 26 '20 at 19:34
  • @JohnScalo Yes, having an active audio session is a necessary condition. But it isn't always a sufficient condition. – matt Aug 26 '20 at 19:39
0

You can do this by making the app active background. I am doing this in my app. I am using location manager api to make the app active in background. Then start playing a audio in background with the help of timer. You can use this link https://github.com/voyage11/Location to make the app active in background.Hope this will help.