iOS开发基础102-后台保活方案
iOS系统在后台执行程序时,有严格的限制,为了更好地管理资源和电池寿命,iOS会限制应用程序在后台的运行时间。然而,iOS提供了一些特定的策略和技术,使得应用程序可以在特定场景下保持后台运行(即“后台保活”)。以下是iOS中几种常见的后台保活方案,并附上示例代码:
一、后台任务
利用beginBackgroundTask和endBackgroundTask来执行后台任务。后台任务将在应用程序进入后台时仍能保持有限的时间执行任务。
#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-后台保活方案的更多相关文章
- 《推送开发全面盘点当前Android后台保活方案的真实运行效果》
登录 立即注册 TCP/IP详解 资讯 动态 社区 技术精选 首页 即时通讯网›专项技术区›推送开发全面盘点当前Android后台保活方案的真实运行效果(截止2 ... 帖子 打赏 分 ...
- 全面盘点当前Android后台保活方案的真实运行效果(截止2019年前)
本文原作者“minminaya”,作者网站:minminaya.cn,为了提升文章品质,即时通讯网对内容作了幅修订和改动,感谢原作者. 1.引言 对于IM应用和消息推送服务的开发者来说,在Androi ...
- IOS开发基础环境搭建
一.目的 本文的目的是windows下IOS开发基础环境搭建做了对应的介绍,大家可根据文档步骤进行mac环境部署: 二.安装虚拟机 下载虚拟机安装文件绿色版,点击如下文件安装 获取安装包: ...
- 【1】windows下IOS开发基础环境搭建
一.目的 本文的目的是windows下IOS开发基础环境搭建做了对应的介绍,大家可根据文档步骤进行mac环境部署: 二.安装虚拟机 下载虚拟机安装文件绿色版,点击如下文件安装 获取安装包: ...
- IOS开发基础知识碎片-导航
1:IOS开发基础知识--碎片1 a:NSString与NSInteger的互换 b:Objective-c中集合里面不能存放基础类型,比如int string float等,只能把它们转化成对象才可 ...
- iOS开发——总结篇&IOS开发基础知识
IOS开发基础知识 1:Objective-C语法之动态类型(isKindOfClass, isMemberOfClass,id) 对象在运行时获取其类型的能力称为内省.内省可以有多种方法实现. 判断 ...
- iOS开发基础-九宫格坐标(6)
继续对iOS开发基础-九宫格坐标(5)中的代码进行优化. 优化思路:把字典转模型部分的数据处理操作也拿到模型类中去实现,即将 ViewController 类实现中 apps 方法搬到 WJQAppI ...
- iOS开发基础-九宫格坐标(5)
继续在iOS开发基础-九宫格坐标(4)的基础上进行优化. 一.改进思路 1)iOS开发基础-九宫格坐标(4)中 viewDidLoad 方法中的第21.22行对控件属性的设置能否拿到视图类 WJQAp ...
- iOS开发基础-九宫格坐标(4)
对iOS开发基础-九宫格坐标(3)的代码进行进一步优化. 新建一个 UIView 的子类,并命名为 WJQAppView ,将 appxib.xib 中的 UIView 对象与新建的视图类进行关联. ...
- iOS开发基础-九宫格坐标(3)之Xib
延续iOS开发基础-九宫格坐标(2)的内容,对其进行部分修改. 本部分采用 Xib 文件来创建用于显示图片的 UIView 对象. 一.简单介绍 Xib 和 storyboard 的比较: 1) X ...
随机推荐
- k8s其它学习链接
k8s弹性伸缩概念以及测试用例 https://www.cnblogs.com/jasonboren/p/11493347.html CKA看这一篇就够了 k8s官网 k8s基础之六 有状态和无状态的 ...
- flask3之CBV和session
flask的CBV CBV书写案例 from flask import Flask app=Flask(__name__) #FBA @app.route("/") def ind ...
- call failed:, {"errMsg": "canvasToTempFilePath:fail invalid viewId"}苹果设备保存离屏 canvas 问题
call failed:, {"errMsg": "canvasToTempFilePath:fail invalid viewId"}苹果设备保存离屏 can ...
- 三:nacos的配置中心
配置中心的使用: 编辑当前项目的pom.xml,加入必要的依赖配置 <!-- spring-cloud-alibaba-dependencies 依赖同注册中心 --> <depen ...
- python利用flux基本读写influxDB
1.读取 QuerApi 形式 python 利用 flux 语句查询 influxdb 数据. https://influxdb-client.readthedocs.io/en/latest/ap ...
- c++从零实现reactor高并发服务器!!!
环境准备 linux虚拟机 安装升级c/c++编译器 gcc/g++ 选项 源代码文件1 源代码文件2 ... 源代码文件n -o指定输出的文件名(不能和源文件同名 默认是a.out) -g调试 -O ...
- OOP课第二阶段总结
OOP课第二阶段总结 前言 作为第二次3+1的总结,明显感受到了此次题目集越来越复杂,结合了实际的物理知识来解决现实中的电路问题.因为电路可以一直扩展下去,情况千变万化,难以像上次题目集一样找到一个呆 ...
- C#开源实用的工具类库,集成超过1000多种扩展方法
前言 今天大姚给大家分享一个C#开源(MIT License).免费.实用且强大的工具类库,集成超过1000多种扩展方法增强 .NET Framework 和 .NET Core的使用效率:Z.Ext ...
- python获取豆瓣电影TOP250的所有电影的相关信息
参考文档:https://weread.qq.com/web/reader/37132a705e2b2f37196c138k98f3284021498f137082c2e 说明:我才接触网络爬虫,在看 ...
- c# HttpWebRequest 解决 请求HTTPS慢
其实就几行代码 if (strUrl.StartsWith("https", StringComparison.OrdinalIgnoreCase)) { request.Cred ...