iOS系统在后台执行程序时,有严格的限制,为了更好地管理资源和电池寿命,iOS会限制应用程序在后台的运行时间。然而,iOS提供了一些特定的策略和技术,使得应用程序可以在特定场景下保持后台运行(即“后台保活”)。以下是iOS中几种常见的后台保活方案,并附上示例代码:

一、后台任务

利用beginBackgroundTaskendBackgroundTask来执行后台任务。后台任务将在应用程序进入后台时仍能保持有限的时间执行任务。

#import <UIKit/UIKit.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;
@property (assign, nonatomic) UIBackgroundTaskIdentifier bgTask; @end @implementation AppDelegate - (void)applicationDidEnterBackground:(UIApplication *)application {
self.bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
[[UIApplication sharedApplication] endBackgroundTask:self.bgTask];
self.bgTask = UIBackgroundTaskInvalid;
}]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 在这里执行你的后台任务
for (int i = 0; i < 100; i++) {
NSLog(@"Background task running %d", i);
[NSThread sleepForTimeInterval:1];
} [[UIApplication sharedApplication] endBackgroundTask:self.bgTask];
self.bgTask = UIBackgroundTaskInvalid;
});
} @end

二、使用Background Fetch

利用Background Fetch,系统会间歇性地唤醒应用程序,以便它可以执行任务或获取数据。需要在Xcode的“Capabilities”中开启Background Modes,并勾选“Background fetch”。

#import <UIKit/UIKit.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[application setMinimumBackgroundFetchInterval:UIApplicationBackgroundFetchIntervalMinimum];
return YES;
} - (void)application:(UIApplication *)application performFetchWithCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
// 在这里执行你的后台数据获取任务
NSLog(@"Background fetch started"); // 模拟数据获取
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"Background fetch completed");
completionHandler(UIBackgroundFetchResultNewData);
});
} @end

三、使用远程通知(Silent Push Notification)

利用远程通知,在接收到通知时,系统会唤醒应用程序执行指定的任务。需要开启Remote notifications,在Application Capabilities中勾选“Remote notifications”。

#import <UIKit/UIKit.h>
#import <UserNotifications/UserNotifications.h> @interface AppDelegate : UIResponder <UIApplicationDelegate, UNUserNotificationCenterDelegate> @property (strong, nonatomic) UIWindow *window; @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[UNUserNotificationCenter currentNotificationCenter].delegate = self;
[[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:(UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted) {
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
}];
return YES;
} - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
// 在这里处理收到的远程通知
NSLog(@"Received remote notification"); // 模拟处理任务
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"Handled remote notification");
completionHandler(UIBackgroundFetchResultNewData);
});
} @end

四、使用特定的后台模式(Background Modes)

iOS提供了一些特定的后台模式,允许程序在后台持续运行。常见的后台模式包括:

  • Audio: 允许应用程序在后台播放音频。
  • Location: 允许应用程序在后台持续获取位置更新。
  • VoIP: 允许应用程序在后台侦听VoIP事件。
  • Bluetooth: 允许应用程序与蓝牙设备通信。

1. Audio后台模式

需要在Xcode的“Capabilities”中开启Background Modes,并勾选“Audio, AirPlay, and Picture in Picture”。

#import <AVFoundation/AVFoundation.h>

@interface AppDelegate ()

@property (nonatomic, strong) AVAudioPlayer *audioPlayer;

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSError *error = nil;
NSURL *audioURL = [[NSBundle mainBundle] URLForResource:@"audioFileName" withExtension:@"mp3"];
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:audioURL error:&error];
[self.audioPlayer prepareToPlay]; AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayback error:&error];
[audioSession setActive:YES error:&error]; return YES;
} - (void)applicationDidEnterBackground:(UIApplication *)application {
[self.audioPlayer play];
} @end

2. Location后台模式

需要在Xcode的“Capabilities”中开启Background Modes,并勾选“Location updates”。

#import <CoreLocation/CoreLocation.h>

@interface AppDelegate () <CLLocationManagerDelegate>

@property (nonatomic, strong) CLLocationManager *locationManager;

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
[self.locationManager requestAlwaysAuthorization];
return YES;
} - (void)applicationDidEnterBackground:(UIApplication *)application {
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[self.locationManager startUpdatingLocation];
} - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray<CLLocation *> *)locations {
CLLocation *location = [locations lastObject];
NSLog(@"Background location: %@", location);
} @end

五、使用后台URLSession

使用NSURLSession来执行后台下载和上传任务。需要在后台配置中开启Background Modes,并勾选“Background fetch”和“Remote notifications”。

#import <UIKit/UIKit.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate, NSURLSessionDelegate, NSURLSessionDownloadDelegate>

@property (strong, nonatomic) UIWindow *window;
@property (nonatomic, strong) NSURLSession *backgroundSession; @end @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
NSURLSessionConfiguration *config = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"com.example.background"];
self.backgroundSession = [NSURLSession sessionWithConfiguration:config delegate:self delegateQueue:nil];
return YES;
} - (void)applicationDidEnterBackground:(UIApplication *)application {
NSURL *url = [NSURL URLWithString:@"http://example.com/largefile.zip"];
NSURLSessionDownloadTask *downloadTask = [self.backgroundSession downloadTaskWithURL:url];
[downloadTask resume];
} - (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location {
NSLog(@"Download completed: %@", location);
// 处理下载结果,比如保存文件
} @end

通过上述几种方案,我们可以在iOS应用程序中实现各种场景下的后台保活。每种方案都有其适用的场景和限制,开发者需要根据应用的实际需求和系统提供的特性,选择合适的后台保活方案。

iOS开发基础102-后台保活方案的更多相关文章

  1. 《推送开发全面盘点当前Android后台保活方案的真实运行效果》

        登录 立即注册 TCP/IP详解 资讯 动态 社区 技术精选 首页   即时通讯网›专项技术区›推送开发全面盘点当前Android后台保活方案的真实运行效果(截止2 ...   帖子 打赏 分 ...

  2. 全面盘点当前Android后台保活方案的真实运行效果(截止2019年前)

    本文原作者“minminaya”,作者网站:minminaya.cn,为了提升文章品质,即时通讯网对内容作了幅修订和改动,感谢原作者. 1.引言 对于IM应用和消息推送服务的开发者来说,在Androi ...

  3. IOS开发基础环境搭建

    一.目的 本文的目的是windows下IOS开发基础环境搭建做了对应的介绍,大家可根据文档步骤进行mac环境部署: 二.安装虚拟机 下载虚拟机安装文件绿色版,点击如下文件安装 获取安装包:       ...

  4. 【1】windows下IOS开发基础环境搭建

    一.目的 本文的目的是windows下IOS开发基础环境搭建做了对应的介绍,大家可根据文档步骤进行mac环境部署: 二.安装虚拟机 下载虚拟机安装文件绿色版,点击如下文件安装 获取安装包:       ...

  5. IOS开发基础知识碎片-导航

    1:IOS开发基础知识--碎片1 a:NSString与NSInteger的互换 b:Objective-c中集合里面不能存放基础类型,比如int string float等,只能把它们转化成对象才可 ...

  6. iOS开发——总结篇&IOS开发基础知识

    IOS开发基础知识 1:Objective-C语法之动态类型(isKindOfClass, isMemberOfClass,id) 对象在运行时获取其类型的能力称为内省.内省可以有多种方法实现. 判断 ...

  7. iOS开发基础-九宫格坐标(6)

    继续对iOS开发基础-九宫格坐标(5)中的代码进行优化. 优化思路:把字典转模型部分的数据处理操作也拿到模型类中去实现,即将 ViewController 类实现中 apps 方法搬到 WJQAppI ...

  8. iOS开发基础-九宫格坐标(5)

    继续在iOS开发基础-九宫格坐标(4)的基础上进行优化. 一.改进思路 1)iOS开发基础-九宫格坐标(4)中 viewDidLoad 方法中的第21.22行对控件属性的设置能否拿到视图类 WJQAp ...

  9. iOS开发基础-九宫格坐标(4)

    对iOS开发基础-九宫格坐标(3)的代码进行进一步优化. 新建一个 UIView 的子类,并命名为 WJQAppView ,将 appxib.xib 中的 UIView 对象与新建的视图类进行关联. ...

  10. iOS开发基础-九宫格坐标(3)之Xib

    延续iOS开发基础-九宫格坐标(2)的内容,对其进行部分修改. 本部分采用 Xib 文件来创建用于显示图片的 UIView 对象. 一.简单介绍  Xib 和 storyboard 的比较: 1) X ...

随机推荐

  1. 关于EF Core 更新速度随时间越来越慢的解决办法

    关于EF Core更新速度随时间越来越慢的解决办法 概要 本篇主要介绍使用 context.ChangeTracker.Clear() 方法,在通过循环进行批量更新时,通过手动清除跟踪实体以提高性能的 ...

  2. XML Schema 字符串数据类型及约束详解

    字符串数据类型用于包含字符字符串的值.字符串数据类型可以包含字符.换行符.回车符和制表符. 以下是模式中字符串声明的示例: <xs:element name="customer&quo ...

  3. RocketMQ消息过滤机制源码详解

    #RocketMQ提供了2种消息过滤的方式: TAG 过滤 SQL92 过滤 SQL过滤默认是没有打开的,如果想要支持,必须在broker的配置文件中设置:enablePropertyFilter = ...

  4. 带你深入领略 Proxy 的世界

    Proxy 是 es2015 标准规范加入的语法,很可能你只是听说过,但并没有用过,毕竟考虑到兼容的问题,不能轻易地使用 Proxy 特性. 但现在随着各个浏览器的更新迭代,Proxy 的支持度也越来 ...

  5. Xenocode Postbuild——C#代码混淆器使用方法

    安装 不多作赘述 使用步骤 选择[application]选项卡,选择[add],如果添加的是exe,则[Preset]选择第一项,添加的是dll则选择第二项 选择[Protect]选项卡,将两个都勾 ...

  6. MySQL学习笔记-多表查询(上)

    多表查询(上) 一. 多表关系 在实际应用中,根据需求,设计的表结构之间存在联系,联系一般分为以下三种 一对多(多对一) 多对多 一对一 1. 一对多(多对一) 案例:部门与员工的关系,一个部门对应多 ...

  7. itest(爱测试) 开源接口测试,敏捷测试管理平台10.0.0RC1 发布,重点增加压测功能

    一:itest work 简介 itest work 开源敏捷测试管理,包含极简的任务管理,测试管理,缺陷管理,测试环境管理,接口测试,接口Mock,还有压测 ,又有丰富的统计分析,8合1工作站.可按 ...

  8. 震惊!docker镜像还有这些知识你都知道吗

    震惊!docker镜像还有这些知识你都知道吗? 镜像搜索 语法 [root@hmm docker-hello]# docker search -h Flag shorthand -h has been ...

  9. 鸿蒙HarmonyOS实战-ArkTS语言基础类库(并发)

    一.并发 并发是指在一个时间段内,多个事件.任务或操作同时进行或者交替进行的方式.在计算机科学中,特指多个任务或程序同时执行的能力.并发可以提升系统的吞吐量.响应速度和资源利用率,并能更好地处理多用户 ...

  10. 键盘中断,键盘驱动,基于Linux0.11

    键盘,咱们做计算机这一行的自然不必多说,天天与它打交道.但熟归熟,清楚键盘背后的原理吗?键盘上都标有各键的名称,表明了各键所代表的意义,但是计算机是如何知道的?组合键是怎样实现的?按下一个代表字符的键 ...