iOS 后台运行

iOS后台行,一般有两种方式:

1.UIBackgroundTaskIdentifier后台任务标记时,

2.设置后台运行模式,需要有voip,location功能的才行。不然app上线审核肯定是过不了的。

下面是我学习后台运行的尝试过程。

一.首先创建一个项目功程用来测试后台运行情况。这里我参照别人的一篇文章,在后台增加角标值。

直接上代码。

objectivec 复制代码
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // Override point for customization after application launch.
        //注册推送,设置角标也需要 不然角标显示不了
    if(version >= 10.0)
    {
        UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
        [center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error) {
            if (error) { NSLog(@"request authorization error: %@", error); }
        }];
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    }
}

//进入前台,结速后台任务
- (void) applicationWillEnterForeground:(UIApplication *)application
{
    if(_badgeTimer)
    {
        dispatch_source_cancel(_badgeTimer);
        _badgeTimer = nil;
    }
}


//进入后台,开始后台任务,启动定时器每隔一秒给角标加一
- (void)applicationDidEnterBackground:(UIApplication *)application {
    
    //方法一
    [self stratBadgeNumberCount];
}

- (void)stratBadgeNumberCount{
    [UIApplication sharedApplication].applicationIconBadgeNumber = 0;

    if(_badgeTimer)
    {
        dispatch_source_cancel(_badgeTimer);
        _badgeTimer = nil;
    }
    
    //定时器增加角标
    _badgeTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
    dispatch_source_set_timer(_badgeTimer, DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC, 1 * NSEC_PER_SEC);
    dispatch_source_set_event_handler(_badgeTimer, ^{
        
        [UIApplication sharedApplication].applicationIconBadgeNumber++;
    
    });
    dispatch_resume(_badgeTimer);
}

程序运行后,返回后台。程序的角标加到1就不再增加了。 注意如果设置了后台运行模式

voip,locationt等会一直增加的。但是你app里没有这些功能的话app store审核肯定是过不了的。如下图

二.尝试使用UIBackgroundTaskIdentifier后台任务标记时

1) Background Task仅用于执行短时间的任务,APP切换到后台后,可以通过beginBackgroundTaskWithExpirationHandler申请一段时间的后台时间,你的任务应该在这段时间内执行完成,否则会被系统杀死。

2) Background Task的持续时间并不是一个固定值,在不同性能的设备上差别巨大。在iPhone 10上为30秒,这个是我自己测试的,据说,在高性能的设备上则达到180秒。最长持续时间似乎还和当前的资源占用情况有关。

3)beginBackgroundTask和endBackgroundTask必须成对出现如果使用全局的UIBackgroundTaskIdentifier记录后台任务,需要注意每次执行beginBackgroundTask都会生成新的UIBackgroundTaskIdentifier。旧的UIBackgroundTaskIdentifier会被覆盖,则上一个UIBackgroundTaskIdentifier就没有机会执行endBackgroundTask。此时会出现beginBackgroundTask和endBackgroundTask不配对的情况,可能会被系统杀死。

objectivec 复制代码
//进入后台,开始后台任务,启动定时器每隔一秒给角标加一
- (void)applicationDidEnterBackground:(UIApplication *)application {
    
    //方法一
    [self stratBadgeNumberCount];
    [self startBgTask];
}

#pragma mark - 方法一
//开启后台任务
- (void)startBgTask{
    UIApplication *application = [UIApplication sharedApplication];

    if(_bgTask != UIBackgroundTaskInvalid)
    {
        [self endBackgroundTask];
    }

    _bgTask = [application beginBackgroundTaskWithExpirationHandler:^{

        NSLog(@"%f",application.backgroundTimeRemaining);

        //在这个地方重新开启后台任务不启作用
        //[weakSelf startBgTask];
        
        [self endBackgroundTask];
    }];
}

//结束后台任务
- (void) endBackgroundTask
{
    UIApplication *application = [UIApplication sharedApplication];
    [application endBackgroundTask:_bgTask];

    _bgTask = UIBackgroundTaskInvalid;
}

使用UIBackgroundTaskIdentifier后台可以延迟30秒左右就被挂启了。测试结果是角标加到31就不再继续加了。据说以前ios可以延迟180秒。没测过。

三.Background Mode

启用Background Mode后(音频播放、后台定位、VoIP等),是没有后台时间限制的。

objectivec 复制代码
//进入前台,结速后台任务
- (void) applicationWillEnterForeground:(UIApplication *)application
{
//    [self endBackgroundTask];
    if(_badgeTimer)
    {
        dispatch_source_cancel(_badgeTimer);
        _badgeTimer = nil;
    }
}

//进入后台,开始后台任务,启动定时器每隔一秒给角标加一
- (void)applicationDidEnterBackground:(UIApplication *)application {
    
    [self stratBadgeNumberCount];

    [self.player play];
    
    //用AVAudioPlayer或CLLocationManager其一就可以
    //方法三 (还没验证)
//    self.appleLocationManager = [[CLLocationManager alloc] init];
//    self.appleLocationManager.allowsBackgroundLocationUpdates = YES;
//    self.appleLocationManager.desiredAccuracy = kCLLocationAccuracyBest;
//    self.appleLocationManager.delegate = self;
//    [self.appleLocationManager requestAlwaysAuthorization];
//    [self.appleLocationManager startUpdatingLocation];

}

- (void)stratBadgeNumberCount{
    [UIApplication sharedApplication].applicationIconBadgeNumber = 0;

    if(_badgeTimer)
    {
        dispatch_source_cancel(_badgeTimer);
        _badgeTimer = nil;
    }
    
    //定时器增加角标
    _badgeTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
    dispatch_source_set_timer(_badgeTimer, DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC, 1 * NSEC_PER_SEC);
    dispatch_source_set_event_handler(_badgeTimer, ^{
        
        [UIApplication sharedApplication].applicationIconBadgeNumber++;
    
    });
    dispatch_resume(_badgeTimer);
}

#pragma mark
- (AVAudioPlayer *)player{
    if (!_player){
        NSURL *url=[[NSBundle mainBundle]URLForResource:@"work5.mp3" withExtension:nil];
        _player = [[AVAudioPlayer alloc]initWithContentsOfURL:url error:nil];
        [_player prepareToPlay];
        //一直循环播放
        _player.numberOfLoops = -1;
        AVAudioSession *session = [AVAudioSession sharedInstance];
        [session setCategory:AVAudioSessionCategoryPlayback error:nil];

        [session setActive:YES error:nil];
    }
    return _player;
}



#pragma mark
/** 苹果_用户位置更新后,会调用此函数 */
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations{
    [self.appleLocationManager stopUpdatingLocation];
    self.appleLocationManager.delegate = nil;

    [UIApplication sharedApplication].applicationIconBadgeNumber++;
    NSLog(@"success");
}

/** 苹果_定位失败后,会调用此函数 */
- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error{
    [self.appleLocationManager stopUpdatingLocation];
    self.appleLocationManager.delegate = nil;
    NSLog(@"error");
}

同时要加上后台运行的能力

参考:iOS 关于后台持续运行 - 简书

相关推荐
游戏开发爱好者81 天前
日常开发与测试的 App 测试方法、查看设备状态、实时日志、应用数据
android·ios·小程序·https·uni-app·iphone·webview
黑码哥1 天前
ViewHolder设计模式深度剖析:iOS开发者掌握Android列表性能优化的实战指南
android·ios·性能优化·跨平台开发·viewholder
2501_915106321 天前
app 上架过程,安装包准备、证书与描述文件管理、安装测试、上传
android·ios·小程序·https·uni-app·iphone·webview
2501_915106321 天前
使用 Sniffmaster TCP 抓包和 Wireshark 网络分析
网络协议·tcp/ip·ios·小程序·uni-app·wireshark·iphone
熊猫钓鱼>_>1 天前
移动端开发技术选型报告:三足鼎立时代的开发者指南(2026年2月)
android·人工智能·ios·app·鸿蒙·cpu·移动端
徐同保2 天前
通过ip访问nginx的服务时,被第一个server重定向了,通过设置default_server解决这个问题
ios·iphone
2501_915918412 天前
在 iOS 环境下查看 App 详细信息与文件目录
android·ios·小程序·https·uni-app·iphone·webview
2501_916007472 天前
没有 Mac 用户如何上架 App Store,IPA生成、证书与描述文件管理、跨平台上传
android·macos·ios·小程序·uni-app·iphone·webview
夏幻灵3 天前
HTTPS全面解析:原理、加密机制与证书体
ios·iphone
TheNextByte13 天前
如何在iPhone上恢复已删除的笔记的综合指南
笔记·ios·iphone