iOS 백그라운드 장시간 실행
일반적으로 앱 이 홈 버튼 을 누 르 고 걸 리 면 이때 앱 의 backgroundTime Remaining 은 백 스테이지 운행 시간 이 약 3 분 밖 에 안 되 는데 앱 을 종료 한 후에 12 분 또는 더 긴 시간 이 지나 면 앱 이 처음 열 렸 을 때의 상태,즉 첫 페이지 로 돌아간다.어떤 항목 은 걸 린 후에 배경 에서 일정 시간 을 실행 하여 서버 와 연결 하 는 작업 을 완성 하거나 계속 실행 해 야 하 는 수요 가 있 습 니 다.필요 하 다 면 앱 이 걸 린 뒤 백그라운드 운영 시간 을 연장 하기 위해 백 스테이지 신청 을 한다.
앱 이 백 스테이지 운영 을 신청 하 는 방식 은 몇 가지 가 있 습 니 다.
음악 을 틀다
포 지 셔 닝
Newsstand downloads
fetch 등;
여기 서 주로 배경 에서 소리 없 는 음악 을 재생 하고(사실은 재생 하지 않 는 다)어떤 방식 으로 위의 그림 을 선택 하 는 지 말한다.제 프로젝트 에 오디 오 재생 수요 가 있 습 니 다.없 으 면 오디 오 를 재생 하 는 이 유 를 찾 거나 다른 방식 으로 이 루어 집 니 다.
이루어지다
여기 서 두 가지 사례 를 사용 했다.전화 모니터링(XKTelManager),백 스테이지 운행(XKBGrunManager),전화 모니터링 은 무시 하고 상황 에 따라 사용 할 수 있다.단 례 를 채택 하 는 것 은 관 리 를 편리 하 게 하기 위 한 것 이다.
XKTelManager.h
#import <Foundation/Foundation.h>
@interface XKTelManager : NSObject
///
@property (nonatomic,assign) BOOL inBackgroundRun;
+ (XKTelManager *)sharedManager;
/**
*/
- (void)startMonitor;
@end
XKTelManager.m
#import "XKTelManager.h"
#import "XKBGRunManager.h"
#import <CoreTelephony/CTCallCenter.h>
#import <CoreTelephony/CTCall.h>
static XKTelManager *_sharedManger;
@interface XKTelManager()
@property (nonatomic, strong) CTCallCenter *callCenter;
@end
@implementation XKTelManager
+ (XKTelManager *)sharedManager{
static dispatch_once_t onceTelSingle;
dispatch_once(&onceTelSingle, ^{
if (!_sharedManger) {
_sharedManger = [[XKTelManager alloc]init];
}
});
return _sharedManger;
}
- (instancetype)init{
self = [super init];
if (self) {
_inBackgroundRun = NO;
}
return self;
}
#pragma mark -*********
- (void)startMonitor {
__weak typeof(self) weakSelf = self;
_callCenter = [[CTCallCenter alloc] init];
_callCenter.callEventHandler = ^(CTCall * call) {
/// ,
if (weakSelf.inBackgroundRun) {
return;
}
///APP
if ([call.callState isEqualToString:CTCallStateDisconnected]){
NSLog(@" --- ");
[[XKBGRunManager sharedManager] stopBGRun];
}
else if ([call.callState isEqualToString:CTCallStateConnected]){
NSLog(@" --- ");
}
else if ([call.callState isEqualToString:CTCallStateIncoming]){
NSLog(@" --- ");
[[XKBGRunManager sharedManager] startBGRun];
}
else if ([call.callState isEqualToString:CTCallStateDialing]){
NSLog(@" --- ");
[[XKBGRunManager sharedManager] startBGRun];
}
else {
NSLog(@" --- ");
}
};
}
@end
XKBGRunManager.h
#import <Foundation/Foundation.h>
@interface XKBGRunManager : NSObject
+ (XKBGRunManager *)sharedManager;
/**
*/
- (void)startBGRun;
/**
*/
- (void)stopBGRun;
@end
XKBGRunManager.m
#import "XKBGRunManager.h"
///
static NSInteger _circulaDuration = 60;
static XKBGRunManager *_sharedManger;
@interface XKBGRunManager()
@property (nonatomic,assign) UIBackgroundTaskIdentifier task;
///
@property (nonatomic,strong) AVAudioPlayer *playerBack;
@property (nonatomic, strong) NSTimer *timerAD;
///
@property (nonatomic, strong) NSTimer *timerLog;
@property (nonatomic,assign) NSInteger count;
@end
@implementation XKBGRunManager{
CFRunLoopRef _runloopRef;
dispatch_queue_t _queue;
}
+ (XKBGRunManager *)sharedManager{
static dispatch_once_t onceRunSingle;
dispatch_once(&onceRunSingle, ^{
if (!_sharedManger) {
_sharedManger = [[XKBGRunManager alloc]init];
}
});
return _sharedManger;
}
/// init ,
- (instancetype)init {
if (self = [super init]) {
[self setupAudioSession];
_queue = dispatch_queue_create("com.audio.inBackground", NULL);
//
NSString *filePath = [[NSBundle mainBundle] pathForResource:@"****" ofType:@"mp3"];
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath:filePath];
self.playerBack = [[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:nil];
[self.playerBack prepareToPlay];
// 0.0~1.0, 1.0
self.playerBack.volume = 0.01;
//
self.playerBack.numberOfLoops = -1;
}
return self;
}
- (void)setupAudioSession {
// AudioSession
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
//
NSError *error = nil;
[audioSession setCategory:AVAudioSessionCategoryPlayback withOptions:AVAudioSessionCategoryOptionMixWithOthers error:&error];
if (error) {
NSLog(@"Error setCategory AVAudioSession: %@", error);
}
NSLog(@"%d", audioSession.isOtherAudioPlaying);
NSError *activeSetError = nil;
// AudioSession, app
[audioSession setActive:YES error:&activeSetError];
if (activeSetError) {
NSLog(@"Error activating AVAudioSession: %@", activeSetError);
}
}
/**
*/
- (void)startBGRun{
[self.playerBack play];
[self applyforBackgroundTask];
///
dispatch_async(_queue, ^{
self.timerLog = [[NSTimer alloc] initWithFireDate:[NSDate date] interval:1 target:self selector:@selector(log) userInfo:nil repeats:YES];
self.timerAD = [[NSTimer alloc] initWithFireDate:[NSDate date] interval:_circulaDuration target:self selector:@selector(startAudioPlay) userInfo:nil repeats:YES];
_runloopRef = CFRunLoopGetCurrent();
[[NSRunLoop currentRunLoop] addTimer:self.timerAD forMode:NSDefaultRunLoopMode];
[[NSRunLoop currentRunLoop] addTimer:self.timerLog forMode:NSDefaultRunLoopMode];
CFRunLoopRun();
});
}
/**
*/
- (void)applyforBackgroundTask{
_task =[[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
dispatch_async(dispatch_get_main_queue(), ^{
[[UIApplication sharedApplication] endBackgroundTask:_task];
_task = UIBackgroundTaskInvalid;
});
}];
}
/**
*/
- (void)log{
_count = _count + 1;
NSLog(@"_count = %ld",_count)
}
/**
*/
- (void)startAudioPlay{
_count = 0;
dispatch_async(dispatch_get_main_queue(), ^{
if ([[UIApplication sharedApplication] backgroundTimeRemaining] < 61.0) {
NSLog(@" ");
[self.playerBack play];
[self applyforBackgroundTask];
}
else{
NSLog(@" ");
}/// ,
[self.playerBack stop];
});
}
/**
*/
- (void)stopBGRun{
if (self.timerAD) {
CFRunLoopStop(_runloopRef);
[self.timerLog invalidate];
self.timerLog = nil;
//
[self.timerAD invalidate];
self.timerAD = nil;
[self.playerBack stop];
}
if (_task) {
[[UIApplication sharedApplication] endBackgroundTask:_task];
_task = UIBackgroundTaskInvalid;
}
}
@end
마지막 으로 AppDelegate.m 에 대응 하 는 방법 에서 백 스테이지 실행 을 시작 하고 중지 하면 됩 니 다!이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
View의 레이아웃 방법을 AutoLayout에서 따뜻한 손 계산으로 하면 성능이 9.26배로 된 이야기이 기사는 의 15 일째 기사입니다. 어제는 에서 이었습니다. 손 계산을 권하는 의도는 없고, 특수한 상황하에서 계측한 내용입니다 화면 높이의 10 배 정도의 contentView가있는 UIScrollView 레이아...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.