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. OAI SDR LTE 基站部署

    目录 文章目录 目录 硬件设备要求 物料购买 部署架构图 安装 LTE/EPC 前期准备 运维相关 操作系统要求 内核要求 CPU Frequency scaling,将 CPU 频率打满 eNode ...

  2. MATLAB txt文件抽稀并分为多个txt文件

    chouxi.m a = load("file.txt"); % len = length(a); interval = 9;%间隔+1 b = a(1:interval:end, ...

  3. FFmpeg开发笔记(二十一)Windows环境给FFmpeg集成AVS3解码器

    ​AVS3是中国AVS工作组制定的第三代音视频编解码技术标准,也是全球首个已推出的面向8K及5G产业应用的视频编码标准.AVS工作组于2019年3月9日完成第三代AVS视频标准(AVS3)基准档次的制 ...

  4. Istio(一):服务网格和 Istio 概述

    目录 一.模块概览 二.微服务架构 三.服务网格概述 3.1 服务网格概述 3.2 为什么需要服务网格? 四.istio简介 4.1 Istio 简介 4.2 流量管理 4.3 可观察性 4.4 安全 ...

  5. asp.net core api 3.1 dynamic 入参转json对象

    比如接口 public object GetList(dynamic obj){ //var jElement=(JsonElement)obj;//使用system.text.json处理 var ...

  6. 性能优化陷阱之hash真的比strcmp快吗

    最近网上冲浪的时候看到有人分享了自己最近一次性能优化的经验.我向来对性能是比较敏感的,所以就点进去看了. 然而我越看越觉得蹊跷,但本着"性能问题和性能优化要靠性能测试做依据",我不 ...

  7. MD5计算,一个扩展类,哪里都能用

    最近有同学问到如何计算一个字节数组的MD5值,现在分享一个扩展类,有了它,MD5计算再也不用其他了. 先看示例: string s = "hello world"; var s_m ...

  8. lazyload图片懒加载

    安装 npm i -S vue-lazyload 在src/main.js文件中添加如下内容 import VueLazyload from 'vue-lazyload' Vue.use(VueLaz ...

  9. 剑指Offer-60.把二叉树打印成多行(C++/Java)

    题目: 从上到下按层打印二叉树,同一层结点从左至右输出.每一层输出一行. 分析: 层次打印二叉树,在打印二叉树结点的同时,保存好结点的左右孩子,不断的重复打印,直到需要打印的数组为空即可. 程序: C ...

  10. ES备份恢复

    1.官网提供snap快照备份恢复 https://www.elastic.co/guide/en/elasticsearch/reference/7.9/snapshot-restore.html 环 ...