iOS 後臺永久保活,親測有效
阿新 • • 發佈:2021-01-11
技術標籤:iOSOCobjective-cios
一想到後臺保活,我們最常見的就是音樂播放軟體了,那在我們不是音樂軟體的情況下我們要如何後臺保活呢?
首先我們就要在Background Modes把音樂對應許可權開啟。
這個許可權開啟後,我們的工作就已經完成了1/3了
接下來我就就要在app進入後臺的時候開始播放無聲音的mp3。
我這裡對音樂播放器進行了簡單的封裝,方便使用SXAudioSessionObject
.h
#import <Foundation/Foundation.h> NS_ASSUME_NONNULL_BEGIN @interface SXAudioSessionObject : NSObject /// 建立單利 + (SXAudioSessionObject *)shareManager; /// 建立音樂播放器 - (void)creatAVAudioSessionObject; /// 開始播放音樂 - (void)startPlayAudioSession; /// 停止播放音樂 - (void)stopPlayAudioSession; @end NS_ASSUME_NONNULL_END
.m
#import "SXAudioSessionObject.h" #import <AVFoundation/AVFoundation.h> #import <AudioToolbox/AudioToolbox.h> @interface SXAudioSessionObject() @property (strong, nonatomic) AVAudioPlayer *audioPlayer; @end @implementation SXAudioSessionObject /// 建立單利 + (SXAudioSessionObject *)shareManager{ static SXAudioSessionObject *manager = nil; static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ manager = [[SXAudioSessionObject alloc]init]; }); return manager; } /// 建立音樂播放器 - (void)creatAVAudioSessionObject{ //設定後臺模式和鎖屏模式下依然能夠播放 [[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:nil]; [[AVAudioSession sharedInstance] setActive: YES error: nil]; //初始化音訊播放器 NSError *playerError; NSURL *urlSound = [[NSURL alloc]initWithString:[[NSBundle mainBundle]pathForResource:@"pomodoSound" ofType:@"m4a"]]; _audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:urlSound error:&playerError]; _audioPlayer.numberOfLoops = -1;//無限播放 _audioPlayer.volume = 0; } /// 開始播放聲音 - (void)startPlayAudioSession{ [_audioPlayer play]; } /// 停止播放聲音 - (void)stopPlayAudioSession{ [_audioPlayer stop]; } @end
對這個封裝完,我們就要使用了。後臺保活,我們只需要在進入後臺的時候播放音樂即可,進入前臺我們停止音樂播放
首先我們先要穿件音樂播放器
[[SXAudioSessionObject shareManager] creatAVAudioSessionObject];
接下來就是播放和停止
//應用程式已經進入後臺執行 - (void)applicationDidEnterBackground:(UIApplication *)application { NSLog(@"如果應用程式支援後臺執行,則應用程式已經進入後臺執行"); //如果需要退出後臺,則在這裡加上:exit(0); [[SXAudioSessionObject shareManager] startPlayAudioSession]; //建立一個背景任務去和系統請求後臺執行的時間 }
//應用程式已經進入活動狀態
- (void)applicationDidBecomeActive:(UIApplication *)application{
NSLog(@"應用程式已進入前臺,處於活動狀態");
[[SXAudioSessionObject shareManager] stopPlayAudioSession];
}
同時我們還要建立一下UIBackgroundTaskIdentifier和NSTimer
@property (nonatomic, assign) UIBackgroundTaskIdentifier backgrounTask;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.timer = [NSTimer scheduledTimerWithTimeInterval:5.0 target:self selector:@selector(applyToSystemForMoreTime) userInfo:nil repeats:YES];
[self.timer setFireDate:[NSDate distantPast]];
return YES;
}
#pragma mark - 定時器設定判斷後臺保活時間,如果將要被後臺殺死,重新喚醒
- (void)applyToSystemForMoreTime {
if ([UIApplication sharedApplication].backgroundTimeRemaining < 30.0) {//如果剩餘時間小於30秒
[[UIApplication sharedApplication] endBackgroundTask:self.self.backgrounTask];
self.backgrounTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[[UIApplication sharedApplication] endBackgroundTask:self.self.backgrounTask];
self.backgrounTask = UIBackgroundTaskInvalid;
}];
}
}
上面的程式碼最好寫成,如果進入後臺的時候再啟用定時器,在前臺定時器處於停止狀態即可。