大家好,我是编程小6,很高兴遇见你,有问题可以及时留言哦。
iOS 4 的发布,Apple 于 2010 年开始允许应用程序在后台运行,并从那时起不断发展和改进后台模式。iOS 限制使用后台以改善用户体验并延长电池寿命。您的应用程序可以在特定用例的后台运行的最新位置,包括:播放音频、更新和从服务器获取的内容。
您的任务不属于该类别之一,则后台可能不适合。如果您尝试使用超出警告范围的后台模式来游戏系统,您可能会遇到其应用程序商店中的那些情况。 !
在本后台模式教程中,您将了解您的应用程序可以在后台执行的四件事:
在深入研究之前,这里是 iOS 中可用的基本后台模式的快速概览:
您将在示例应用程序中添加上述上述四种模式以及后台获取。
注意:获得真实的设备上进行操作的时候,它应该是真实的设备上进行的效果。在此期间,当您忘记某个步骤时,应用程序在后台运行。然后,当您切换到可能的真实设备时,可能根本无法工作。
在物理设备上运行项目之前,您必须设置您的开发团队,如下所示:
四个运行并运行以感受睡眠永不停止的应用程序,因为后台执行它 - 一个不受干扰的项目模式,这是一个项目模式:
您要添加的第一个功能是背景音频。
在物理设备上制造和运行时不眠不休。到音频选项卡,播放音乐,然后通过返回主屏幕将导航应用程序显示后台。音乐将停止播放。
打开AudioModel.swift 。
该应用程序利用研究观察曲目AVQueuePlayer
并顺序播放。该模型玩家的currentItem
价值以提供对视图的按更新。
启动项目包括来自流行音乐网站的免费作品。com的音频文件。您可以通过名称免费使用音乐。这三首歌都是凯文麦克劳德的:
感谢美好的音乐,凯文!
注意:查看文档Apple的UIKit中应用程序的执行状态,以了解活动状态和其他内容的更多相关信息。
应用进入后台时音乐停止?好吧,还有一个关键的部分!
让您启用指示应用程序运行的特定功能,否则大部分后台应用程序都可以在后台执行任务,从而实现任何关键功能。
之后,音频会通知iOS 继续是音频,即使——自动应用程序的后台播放模式也是你的背景激活。几乎是你需要激活它。
返回 Xcode 并执行以下操作:
中,画背景模式以添加此功能展开背景模式功能,然后启用画幅 、AirPlay和画框以音频背景。
在这样的物理设备上制造和运行应用程序。之前开始一样的音乐,然后应用程序。这次视频将继续。就是简单!
如此,您将更新后台继续接收位置,即使应用程序后台管理如此。
首先,构建并运行应用程序。选择位置选项并点击什么都不会发生,因为你会开始一些重要的步骤。你现在改变它。
打开LocationModel.swift。这是向LocationView提供位置数据的代码。你要做一个简单的改变init()
. 替换以下两行:
mgr.requestWhenInUseAuthorization()
mgr.allowsBackgroundLocationUpdates = false
和:
mgr.requestAlwaysAuthorization()
mgr.allowsBackgroundLocationUpdates = true
即使应用程序未使用,第一行也会请求位置更新。第二个请求甚至在后台更新。
返回到Signing & Capabilities屏幕并选中 位置更新复选框,让 iOS 知道您的应用想要在后台接收位置更新。
除了选中此框外,iOS 还要求您在Info.plist 中设置一个键,向用户解释您需要后台更新的原因。如果您不包括此内容,则位置请求将静默失败。
打开Info.plist并添加Privacy - Location Always and When In Use Usage Description和Privacy - Location When In Use Usage Description的键。然后键入应用程序将在地图上显示您的位置作为两个键的值。
现在,构建并运行!切换到位置选项卡并点击开始。
首次加载时,您会看到您在位置隐私原因中写入的消息。
在使用应用程序时点击允许并在建筑物外或周围散步——尽量不要太分心捕捉口袋妖怪。
位置更新应该开始出现。如果没有,请再次将应用程序发送到后台以触发始终提示进行位置跟踪。您还可以使用“设置” 应用在隐私 ▸ 定位服务 ▸ 不眠设置中启用“不眠”应用的始终跟踪。
如果您将应用程序发送到后台,您仍会在控制台中看到位置更新。
一段时间后,您应该会看到如下内容:
如果您退出应用程序,您应该会在控制台日志中看到应用程序更新位置。再次打开它以查看地图上的所有图钉,显示您在步行期间去过的地方。
如果您使用的是模拟器,您也可以使用它来模拟运动!查看功能 ▸ 位置菜单:
轻而易举,对吧?进入第三个选项卡和第三个背景模式!
下一个后台模式正式称为Extending Your App's Background Execution Time。多么拗口。任务完成更容易说!
从技术上讲,这根本不是后台模式。您不必声明您的应用在 Capabilities 中使用它。它是一种 API,可让您在应用程序处于后台时在有限的时间内运行任意代码,从而为您提供更多时间来完成关键任务,例如保存数据。
Completion后台模式的一个有效用例是完成一些关键任务,例如保存用户的输入或发布交易。有很多可能性。
由于代码是任意的,您可以使用此 API 执行几乎任何操作:执行冗长的计算、对图像应用过滤器、渲染复杂的 3D 网格 — 随便!你的想象力是极限,只要你记住你只能得到一些时间,而不是无限的时间。稍后,您将设置一个在后台运行的冗长计算,以便了解此 API 的工作原理。
iOS 决定了你的应用程序移到后台后的时间。无法保证您被授予的时间,但您可以随时查看UIApplication.shared.backgroundTimeRemaining
. 这将告诉您还剩多少时间。
一般的,基于观察的共识是你得到大约 30 秒。同样,没有任何保证,API 文档甚至没有给出估计值——所以不要依赖这个数字。您可能会得到 5 分钟或 5 秒的时间,因此您的应用需要为中断做好准备。当您的时间快到时,iOS 会向您发出回调信号。
这是每个计算机科学专业的学生都应该熟悉的一项常见任务:计算斐波那契数列中的数字。这里的转折是,您将在应用程序移至后台后计算这些数字!
打开CompleteTaskModel.swift并查看已经存在的内容。就目前而言,此视图将按顺序计算斐波那契数并显示结果。
如果您现在要在实际设备上暂停应用程序,则计算将停止并在应用程序再次激活时恢复原状。你的任务是创建一个后台任务,这样计算就可以继续运行,直到 iOS 说“时间到了!”
您首先需要将以下内容添加到CompleteTaskModel
:
var backgroundTask: UIBackgroundTaskIdentifier = .invalid
此属性标识要在后台运行的任务请求。
接下来将以下方法添加到CompleteTaskModel
之前resetCalcuation()
:
func registerBackgroundTask () {
backgroundTask = UIApplication .shared.beginBackgroundTask { [ weak self ] in
print ( "iOS has signaled time has expired" )
self ?.endBackgroundTaskIfActive()
}
}
registerBackgroundTask()
告诉 iOS,当应用程序移至后台时,您需要更多时间来完成您正在做的任何事情。返回的值是此任务的标识符,以便您可以在完成时告诉 iOS。在此调用之后,如果您的应用程序移动到后台,它仍然会获得 CPU 时间,直到您调用endBackgroundTask(_:)
.
好吧,至少有一些 CPU 时间。
endBackgroundTask(_:)
如果你在后台一段时间后不调用,iOS 会调用你调用时定义的闭包beginBackgroundTask(expirationHandler:)
。这使您有机会停止执行代码。
所以最好打电话endBackgroundTask(_:)
告诉系统你已经完成了。如果您在此块运行后不调用它并继续执行代码,iOS 将终止您的应用程序!
在下面添加此方法registerBackgroundTask()
:
func endBackgroundTaskIfActive () {
let isBackgroundTaskActive = backgroundTask != .invalid
if isBackgroundTaskActive {
print ( "后台任务结束。" )
UIApplication .shared.endBackgroundTask(backgroundTask)
背景任务= .invalid
}
}
如果它被主动注册并将其 ID 重置为invalid ,这将结束后台任务。
现在,对于重要的部分:更新onChangeOfScenePhase(_:)
以注册和结束后台任务,具体取决于应用程序是移动到后台还是活动状态。
将这两个 case 语句替换为以下内容:
case .background:
让isTimerRunning = updateTimer != nil
让isTaskUnregistered = backgroundTask == .invalid
if isTimerRunning && isTaskUnregistered {
注册背景任务()
}
案子.活动:
endBackgroundTaskIfActive()
当更改为后台状态时,这会在任务运行但未注册时注册任务。当变为活动状态时,它将结束后台任务。
在beginPauseTask()
中,在后面添加这一行updateTimer = nil
:
endBackgroundTaskIfActive()
现在,当用户停止计算时,您调用endBackgroundTask(_:)
以向 iOS 表明您不需要任何额外的 CPU 时间。
注意: endBackgroundTask(_:)
每次打电话时都打电话很重要beginBackgroundTask(expirationHandler:)
。如果您调用beginBackgroundTask(expirationHandler:)
两次并且只调用endBackgroundTask(_:)
其中一个任务,您仍然会获得 CPU 时间,直到您endBackgroundTask(_:)
使用第二个后台任务的标识符再次调用。
构建并运行,然后切换到第三个选项卡。
点击播放并观看应用程序计算那些甜蜜的斐波那契值。将应用程序发送到后台,但在 Xcode 的控制台中观察输出。您的应用程序应在剩余时间减少时继续更新数字。
在大多数情况下,这个时间会从 30 秒开始下降到 5 秒。如果您在达到 5 秒(或您看到的任何值)时等待时间到期,iOS 会调用到期块。
您的应用应该很快就会停止生成输出。然后,如果您返回应用程序,计时器应该再次开始触发,斐波那契疯狂将继续。
在活动和后台之间切换,看看您如何通过每次切换获得额外的时间块。
关于本后台模式教程的最后一个主题:后台获取。
iOS 7 中引入了后台获取。它可以让您的应用程序保持最新状态,同时最大限度地减少对电池寿命的影响。从 iOS 13 开始,Apple 引入了一个新的后台任务调度程序 API,它提供了显着的改进。
例如,假设您正在应用程序中实现新闻提要。在后台获取之前,您将在每次应用启动时刷新提要。
可悲的是,当刷新发生时,用户会在几秒钟内看到旧标题。你知道有些人会试图点击一个故事,结果却发现它消失了,取而代之的是一个不相关的故事。不好看。
如果用户打开您的应用程序时神奇地出现了最新的头条新闻,那不是更好吗?这是后台获取给你的能力。
启用后,系统会利用使用模式来确定何时触发后台提取。例如,如果用户在大多数情况下在上午 9 点打开您的新闻应用程序,则可能会在上午 9 点之前的某个时间发生后台抓取。系统决定发出后台抓取的最佳时间,因此,它不适合关键更新。
后台获取由BGTaskScheduler控制,这是一个复杂的系统,用于平衡影响用户体验的所有因素,例如性能、使用模式、电池寿命等。
后台获取通常涉及从外部源(如网络服务)获取信息。出于本背景模式教程的目的,您将获取当前时间并且不会使用网络。
为了实现后台获取,您需要执行这些任务——但不要执行它们:
Info.plist
为您的刷新任务添加一个标识符。BGTaskScheduler.register(forTaskWithIdentifier:using:launchHandler:)
以处理后台获取。BGAppRefreshTaskRequest
用于earliestBeginDate
何时执行的。BGTaskScheduler.submit(_:)
。与后台完成任务类似,您有一个短暂但不确定的时间框架来执行后台获取。共识数字是最多 30 秒,但计划更少。如果您需要下载大型资源作为提取的一部分,请使用URLSession
的后台传输服务。
是时候开始了。首先,简单的部分:检查Signing & Capabilities下的 Background fetch mode 功能。**
接下来,打开Info.plist
并点击 + 以添加新标识符。
向下滚动并选择Permitted background task scheduler identifiers。展开该项目,然后点击该新标识符旁边的 +以添加一个条目。
键入com.mycompany.myapp.task.refresh作为标识符的值。
注意:在您的实际项目中,您将反向使用您公司的 URL 作为标识符的根,添加您的应用程序名称和描述性元素,例如task.refresh。您可以定义多种刷新任务,每种都有自己的标识符。
接下来,您需要一个AppDelegate
类,因为 iOS 期望您在application(_:didFinishLaunchingWithOptions:)
.
在App文件夹中,添加一个名为AppDelegate.swift的新 Swift 文件。然后用以下代码替换现有代码:
导入UIKit
导入BackgroundTasks
类 AppDelegate : UIResponder , UIApplicationDelegate {
static var dateFormatter: DateFormatter = {
let formatter = DateFormatter ()
格式化程序.dateStyle = .short
formatter.timeStyle = .long
返回格式化程序
}()
变量窗口:UIWindow?
func 应用程序(
_ 应用程序:UIApplication,
didFinishLaunchingWithOptions launchOptions:[ UIApplication.LaunchOptionsKey:Any ] ?= nil ) -
> Bool {
return true
}
}
此代码为刷新时间戳定义了一个日期格式化程序。它还包括一个空方法application(_:didFinishLaunchingWithOptions:)
,用于注册后台获取任务。
现在将以下函数添加到AppDelegate
:
func refresh () {
// 模拟一次刷新,只需将上次刷新日期
// 更新为当前日期/时间
let formattedDate = Self .dateFormatter.string(from: Date ())
UserDefaults (
格式化日期,
forKey: UserDefaultsKeys .lastRefreshDateKey)
print ( "刷新发生" )
}
这个函数是模拟一次刷新。
在您创建的应用程序中,您可能会从网络中获取数据。对于本教程,您将保存格式化的时间戳以UserDefaults
显示刷新执行的时间。
仍然在AppDelegate.swift中,将以下函数添加到AppDelegate
:
func scheduleAppRefresh () {
让请求= BGAppRefreshTaskRequest (
标识符:AppConstants .backgroundTaskIdentifier)
request.earliestBeginDate = Date (timeIntervalSinceNow: 1 * 60 )
do {
try BGTaskScheduler .shared.submit(request)
print ( "后台刷新计划" )
} catch {
print ( "无法安排应用刷新(error.localizedDescription) " )
}
}
在这里,您创建一个然后从当前时间BGAppRefreshTaskRequest
开始分配一分钟。earliestBeginDate
然后您使用 提交请求BGTaskScheduler.submit(_:)
。
现在,将主体替换为application(_:didFinishLaunchingWithOptions:)
:
BGTaskScheduler .shared.register(
forTaskWithIdentifier: AppConstants .backgroundTaskIdentifier,
using: nil ) { task in
self .refresh() // 1
task.setTaskCompleted(success: true ) // 2
self .scheduleAppRefresh() // 3
}
scheduleAppRefresh()
返回 真
当 iOS 完成启动应用程序时,此代码会将任务注册到任务调度程序并安排第一次刷新。任务本身在执行时将:
现在您需要将您的连接AppDelegate
到AppMain
. 打开AppMain.swift。body
在:之前添加这一行
@UIApplicationDelegateAdaptor ( AppDelegate.self ) var appDelegate _ _
这就是 iOS 调用AppDelegate
.
在物理设备上构建和运行应用程序。检查 Xcode 控制台中的消息以确认已安排后台刷新。
测试后台获取的一种方法是坐下来等待系统决定执行此操作。但是您可能会坐很长时间等待这种情况发生。
iOS 不保证您的刷新何时执行。系统使用多种因素来决定何时执行,例如应用程序使用模式、电池电量等。幸运的是,Xcode 为您提供了一种使用调试器命令触发后台获取的方法。
打开RefreshView.swift并在print("moved to background")
.
然后将应用程序发送到后台,Xcode 应该会在您的新断点处中断。在lldb提示符下,键入(或者,因为它相当复杂,所以复制并粘贴!)以下命令:**
e - l objc -- (void)[[ BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@ "com.mycompany.myapp.task.refresh" ]
这将指示调试器立即执行后台刷新。
恢复应用程序的执行。控制台应显示发生刷新,然后后台刷新计划。每次刷新都会为将来安排另一个刷新。您还可能会看到来自后台任务调度程序的调试消息,指示其活动。
接下来,重新打开应用程序。刷新选项卡将显示刷新发生的时间和日期。
如果您将应用程序留在设备上并在接下来的几天内查看,您会看到时间戳不时更新。iOS 根据其计算的最佳刷新时间来调用刷新。
对于需要几分钟才能完成的长时间运行的后台任务,请了解有关后台处理任务的更多信息。后台处理任务类似于后台提取,但用于更严格的任务,例如数据处理和维护。
还有两个与后台模式相关的优秀 WWDC 演示:
最后,您可以在配置后台执行模式中了解所有后台执行模式。
这里也推荐一些面试相关的内容!
① BAT等各个大厂iOS面试真题+答案大全
② iOS中高级开发必看的热门书籍(经典必看)
③ iOS开发高级面试"简历制作"指导
④ iOS面试流程到基础知识大全