首页 星云 工具 资源 星选 资讯 热门工具
:

PDF转图片 完全免费 小红书视频下载 无水印 抖音视频下载 无水印 数字星空

iOS开发基础102-后台保活方案

编程知识
2024年07月16日 15:27

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应用程序中实现各种场景下的后台保活。每种方案都有其适用的场景和限制,开发者需要根据应用的实际需求和系统提供的特性,选择合适的后台保活方案。

From:https://www.cnblogs.com/chglog/p/18305545
本文地址: http://shuzixingkong.net/article/129
0评论
提交 加载更多评论
其他文章 玄机-第一章 应急响应- Linux入侵排查
玄机-第一章 应急响应- Linux入侵排查 简介 账号:root 密码:linuxruqin ssh root@IP 1.web目录存在木马,请找到木马的密码提交 2.服务器疑似存在不死马,请找到不死马的密码提交 3.不死马是通过哪个文件生成的,请提交文件名 4.黑客留下了木马文件,请找出黑客的服
玄机-第一章 应急响应- Linux入侵排查 玄机-第一章 应急响应- Linux入侵排查 玄机-第一章 应急响应- Linux入侵排查
给博客园的几点现实建议
博客园又遇到了生存危机,老实说,意料之中。 因为,付费会员就能支撑一个完全免费的网站,这种商业模式还没成功过。 博客园的理念我完全理解,但是多听听现实性的建议才是正道。 第一计:祸水东引 博客园不接广告这种坚持我理解,但是,你就不能注册个小号? 比如注册个:hotspot.dev&#160;开发热点
企业级环境部署:在 Linux 服务器上如何搭建和部署 Python 环境?
在大部分企业里,自动化测试框架落地都肯定会集成到Jenkins服务器上做持续集成测试,自动构建以及发送结果到邮箱,实现真正的无人值守测试。 不过Jenkins搭建一般都会部署在公司的服务器上,不会在私人电脑里,而服务器大部分都是Linux操作系统的。所以,我们如果要在Linux上的Jenkins服务
企业级环境部署:在 Linux 服务器上如何搭建和部署 Python 环境? 企业级环境部署:在 Linux 服务器上如何搭建和部署 Python 环境? 企业级环境部署:在 Linux 服务器上如何搭建和部署 Python 环境?
MYSQL DQL in 到底会不会走索引&in 范围查询引发的思考。
前情引子 in 会不会走索引?很多人肯定会回答、废话、如果命中了索引、那肯定会走。 其实我和大多数人一样、一开始也是这么想的、直至有一个血淋淋的案子让我有所改观、有所思考。 背景介绍 业务的工单表、我们分了64张、以userId作为分表键、业务实际场景中未使用到搜索引擎、主要是一些B端业务。 业务有
设计模式之抽象工厂模式(学习笔记)
定义 抽象工厂模式是一种创建型设计模式,它提供一个接口,用于创建一系列相关或依赖的对象,而无需指定它们的具体类。抽象工厂模式将对象的创建过程抽象化,允许子类通过实现具体工厂类来定制对象的创建。 为什么使用抽象工厂模式 产品族的一致性 抽象工厂模式确保同一产品族中的对象之间的一致性。 部分遵循开闭原则
给博客园的寄语
39岁大龄C#开发程序员,今天看到了博客园的求救信,内心不禁一阵触动,故而写下这一篇文章,以此来缅怀我和博客园一起走过的青春。 博客园虽然之前也发过几次求救了,但当时都觉得不至于吧,因为想着坚持这么多年用户基数不小的网站,再怎样维持生存应该不难吧。但这次看到了博客园团队为了运营不惜在借贷维持,我才觉
如何解决 CentOS 7 官方 yum 仓库无法使用的问题
一、背景介绍 2024 年 7 月 1 日,在编译基于 CentOS 7.6.1810 镜像的 Dockerfile 过程中,执行 yum install 指令时,遇到了错误:Could not resolve host: mirrorlist.centos.org; Unknown error。
AI时代你一定要知道的Agent概念
这两年,随着人工智能(AI)和计算能力的发展,AI应用的落地速度大大加快。以ChatGPT为代表的AI应用迅速火遍全球,成为打工人的常用工具。紧接着,多模态、AI Agent等各种高大尚的名词也逐渐进入大众视野,吸引了大量关注。那么,到底什么是AI Agent?下文半支烟将带你详细了解这个概念。 1
AI时代你一定要知道的Agent概念 AI时代你一定要知道的Agent概念