前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >基础篇-iOS后台运行以及相关

基础篇-iOS后台运行以及相关

作者头像
進无尽
发布于 2018-09-12 10:17:03
发布于 2018-09-12 10:17:03
5K0
举报
文章被收录于专栏:進无尽的文章進无尽的文章

与内容无关

前言

对于APP的前后台运行情况的了解,有助于我们在实际开发中规避一些问题,以及采取稳妥的方法处理和解决问题,是很必须的。

应用的运行状态分为以下五种:

  • Not running:应用还没有启动,或者应用正在运行但是途中被系统停止。
  • Inactive:当前应用正在前台运行,但是并不接收事件(当前或许正在执行其它代码)。一般每当应用要从一个状态切换到另一个不同的状态时,中途过渡会短暂停留在此状态。唯一在此状态停留时间比较长的情况是:当用户锁屏时,或者系统提示用户去响应某些(诸如电话来电、有未读短信等)事件的时候。
  • Active:当前应用正在前台运行,并且接收事件。这是应用正在前台运行时所处的正常状态
  • Background:应用处在后台,并且还在执行代码。一般的应用,都只会在这个状态短暂停留(最多十分钟),然后就会被系统强制进入 Suspended 状态。而 iOS 为了在某些情况下提供更好的体验,提供了一些选项,只要满足这些选项的条件,就可以在后台运行很长的一段时间,下面我们将重点讨论可以使应用在后台长时间运行的方法。
  • Suspended:应用处在后台,并且已停止执行代码。系统自动的将应用移入此状态,且在此举之前不会对应用做任何通知。当处在此状态时,应用依然驻留内存但不执行任何程序代码。当系统发生低内存告警时,系统将会将处于 Suspended 状态的应用清除出内存以为正在前台运行的应用提供足够的内存。

想了解更多,推荐一篇很好的文章:iOS应用程序生命周期(前后台切换,应用的各种状态)详解

后台模式

有时候我们想让APP在后台运行,可是苹果对后台模式一直审核很严格,在我看来,苹果限制 app在后台运行,是为了更有效的利用硬件使用当前的app,不然,过多的app驻留后台,对手机资源占用是一大问题。,那么后台模式是什么呢,以及怎样实现呢?

iOS 提供的后台运行方式

上图为 iOS 提供的后台运行方式列表,如果需要,可在 Xcode 的项目设置中开启对应的选项。App Store 的审核人员会检查应用中是否有必要开启该后台运行模式选项,如果应用中不需要,而又开启了这个选项,可能会被拒,并且这部分的审核是很严格的,如果不能提供证据证据,是肯定会被拒

  • Audio, AirPlay and Picture in Picture

此个选项包含四种场景,分别是:音频的播放,录音,AirPlay 及画中画的视频播放。 音频的播放:在播放音频时,即使应用退到后台,只要一直有音频在播放,那应用就可以一直在后台运行。代码实现可参考:http://www.linuxidc.com/Linux/2012-08/68364.htm 录音:应用可以请求使用麦克风,而当开启了此后台选项,应用在使用麦克风的时候,即使退到后台,也可以一直后台运行,通过查看微信安装包中的 plist 文件,微信的语音聊天,就是通过这种方式实现的。而当该类应用退到后台后,iOS 系统的状态栏会变成红色,并在状态栏中显示正在使用麦克风的应用的名称,如下图所示。

正在使用麦克风提示

AirPlay:AirPlay 是指将 iOS 设备,或者 Mac 设备上的音视频,同步到另一个设备中播放。举两个例子,第一个是把 iPhone 上的音乐通过蓝牙的方式在汽车的蓝牙音响播放,第二个是把 iPhone 上的视频,同步到智能电视屏幕上播放。此功能一般用于多端及多屏的交互。关于 AirPlay 的开发文档:http://nto.github.io/AirPlay.html 画中画的视频播放:画中画是 iPad 版本的 iOS 9 新增加的功能,可以在 iOS 的桌面,或者其他应用的界面的上面播放视频,从而该视频区域所属的应用就可以后台运行了。此功能现在只在 iPad 应用中提供。代码实现可参考:http://www.cocoachina.com/ios/20150714/12558.html

  • Location updates

一般用于导航应用中,开启此选项后,应用退到后台,还可以得到系统的定位更新,从而使得应用可以根据定位的变化做出不同的反应。代码实现可参考:https://github.com/voyage11/Location

  • Voice over IP

VOIP 类的应用允许用户使用网络而不是手机打电话,因此这一类的应用需要保持同它相关的服务的网络连接,用以收到来电事件和其他数据。iOS 不是通过一直让该应用处于激活状态来达到这个目的,而是同样也会将这类的应用挂起,但同时会在应用被挂起期间由系统接管它的 VOIP 的 Socket当这个 Socket 有数据通信时系统会再次唤醒处于挂起状态的应用,同时将 Socket 的控制权交还给该应用,以让其正常的处理来电事件和其他数据。 其中VOIP需要绑定一个Socket链接并申明给系统,系统将会在后台接管这个连接, #一旦远端数据过来,你的App将会被唤醒10s(或者更少)的时间来处理数据,超过时间或者处理完毕,程序继续休眠

  • Newsstand downloads

在 iOS 开发中,有一类叫报刊杂志类应用比较特别,在 iOS 9 之前的系统中,此类应用会统一收在系统内置的「报刊杂志」应用中,在 iOS 9 中则去掉了内置的「报刊杂志」应用,此类应用得以以单独的图标入口出现在桌面中。此后台运行的选项就是提供给报刊杂志类应用可以在后台下载及处理报刊杂志内容,而下载的过程需要使用 NewsstandKit 中的 NKAssetDownload 进行下载。需要注意的是,下载的过程中应用可能还是会被挂起甚至应用被退出,而 iOS 会在 Wi-Fi 环境下继续下载,直到下载完成。而一旦下载完成,如果应用只是被挂起,则** iOS 会唤醒对应的应用,回调对应的事件;如果应用已经退出则会启动应用**,在启动参数中会带上对应的标识表示这次启动是因为下载报刊杂志内容完成。代码实现可参考:http://www.viggiosoft.com/blog/blog/2011/10/17/ios-newsstand-tutorial/

  • External Accessory communication

此选项提供给一些 MFi 外设通过蓝牙,或者 Lightning 接头等方式与 iOS 设备连接,从而可在外设发送消息时,唤醒已经被挂起的应用。而一旦被唤醒,一般情况下, 应用只有最多 10 秒钟的执行时间。MFi 外设:是指通过苹果 MFi 认证的设备,而 MFi 认证是对其授权配件厂商生产的外置配件的一种标识使用许可,是 Made for iOS 的英文缩写。

  • Uses Bluetooth LE accessories

此选项与 External Accessory communication 类似,只是此选项无需限制 MFi 外设,而需要的是 Bluetooth LE 设备。

  • Acts as a Bluetooth LE accessory

此选项是指 iOS 设备作为一个蓝牙外设连接时,对应的应用可以后台运行,但是使用此模式需要用户进行授权认证。

  • Background fetch

iOS 7 新增加的一个选项,用于即使在后台,也需要频繁更新数据的应用。例如一个 PM2.5 的应用,需要几个小时更新一次数据,那么可以开启此选项,设置一个时间间隔,从而让 iOS 在间隔时间内在后台启动该应用,执行指定数据的获取工作,而此过程最多只能执行 30 秒钟。代码实现可参考:http://objccn.io/issue-5-5/

  • Remote notifications

iOS 7 新增加的一个选项,是一种静默推送,它有别于一般的推送,应用收到此类推送后,不会有任何的界面提示,而当应用退出或者挂起时收到此类推送,iOS 也会启动或者唤醒对应的应用。例如一个阅读应用,用户订阅的博客更新了,那么可以先发一个静默推送,应用收到此种推送后,可以先把用户订阅的博客内容都下载好,再通知用户,这样用户一打开应用就可以马上开始阅读。收到静默推送,会回调对应的回调方法,而此回调方法最多只能执行 30 秒钟。代码实现可参考:http://objccn.io/issue-5-5/ #需要注意的是: iOS 7 以前,应用进入后台继续运行时,如果用户锁屏了,那么 iOS 会等待应用运行完,才进入睡眠状态。 而在 iOS 7 上,系统会很快进入睡眠状态,那些后台应用也就暂停了。 #如果收到事件被唤醒(例如定时事件、推送、位置更新等),后台应用才能继续运行一会。 因为处理过程变成了断断续续的,因此下载时也要使用 NSURLSession 来处理(即下文中的 Background Transfer Service)。

  • 基于 NSURLSession 的后台传输

此为 iOS 7 新增加的特性,用于在后台下载或者上传大文件,步骤如下:创建后台传输用的 NSURLSession 对象;向这个对象中加入对应的传输的 NSURLSessionTask,并开始传输;在实现 AppDelegate 里实现 -application:handleEventsForBackgroundURLSession:completionHandler: 方法,以刷新 UI 及通知系统传输结束。一旦后台传输的状态发生变化(包括正常结束和失败)的时候,应用将被唤醒并运行 AppDelegate 中的回调。但是也有一些限制,后台传输只会通过 Wi-Fi 来进行。后台下载的时间与以前的关闭应用后X分钟的模式不一样,而是为了节省电力变为离散式的下载。代码实现可以参考:http://onevcat.com/2013/08/ios7-background-multitask/

保持程序在后台长时间运行

iOS为了让设备尽量省电,减少不必要的开销,保持系统流畅,因而对后台机制采用墓碑式的“假后台”。除了系统官方极少数程序可以真后台,一般开发者开发出来的应用程序后台受到以下限制:

  • 用户按Home之后,App转入后台进行运行,此时拥有180s后台时间(iOS7)或者600s(iOS6)运行时间可以处理后台操作
  • 当180S或者600S时间过去之后,可以告知系统未完成任务,需要申请继续完成,系统批准申请之后,可以继续运行,但总时间不会超过10分钟。
  • 当10分钟时间到之后,无论怎么向系统申请继续后台,系统会强制挂起App,挂起所有后台操作、线程,直到用户再次点击App之后才会继续运行。 #申请后台处理时间的方法: //申请后台,该方法只有在App处于激活 beginBackgroundTaskWithExpirationHandler:时调用才有效。 //注销后台 endBackgroundTask: #import "AppDelegate.h" @interface AppDelegate () @property(assign, nonatomic)UIBackgroundTaskIdentifier backIden; @end @implementation AppDelegate - (void)applicationDidEnterBackground:(UIApplication *)application { [self beginTask]; } - (void)applicationWillEnterForeground:(UIApplication *)application { NSLog(@"进入前台"); [self endBack]; } //申请后台 -(void)beginTask { NSLog(@"begin============="); _backIden = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{ #在时间到之前会进入这个block,一般是iOS7及以上是3分钟。 #按照规范,在这里要手动结束后台,你不写也是会结束的,但是不写有可能会crash。 NSLog(@"将要挂起============="); [self endBack]; }]; } //注销后台 -(void)endBack { NSLog(@"end============="); [[UIApplication sharedApplication] endBackgroundTask:_backIden]; _backIden = UIBackgroundTaskInvalid; } @end

使用后台模式可以使APP在后台持续运行,不过下面的这俩方法是很多想实现后台长时间运行的APP都可以尝试的。

  • 有的开发者为了自己的APP能在后台运行想出一直循环播放一段没声音的音频,在后台选项中选择「Audio, AirPlay and Picture in Picture」,而开始循环播放一段是没声音的音频,即在 Audio Unit 回调函数中使用 kAudioUnitRenderAction_OutputIsSilence 标志位,但是这种方式苹果的审核人员如果发现,会被拒,基本上都会被发现。
  • 使用定位服务的方法来保持后台,在程序转入后台的时候,启动定位服务[locationManager startUpdatingLocation];(第一次运行这个方法的时候,如果之前用户没有使用过App,则会弹出是否允许位置服务)。这样在定位服务可用的时候,程序会不断刷新后台时间,实际测试,发现后台180s时间不断被刷新,达到长久后台的目的。
小结

关于应用后台模式运行以及其它相关的知识,后续会持续更新


本文参考文章 iOS开发:后台运行 iOS 后台运行实现

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017.03.13 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Golang 学习笔记-2:控制流
val 始终为集合中对应索引的值拷贝,因此它一般只具有只读性质,对它所做的任何修改都不会影响到集合中原有的值(译者注:如果 val 为指针,则会产生指针的拷贝,依旧可以修改集合中的原值一个字符串是 Unicode 编码的字符(或称之为 rune)集合,因此您也可以用它迭代字符串
goodspeed
2020/12/22
3790
【愚公系列】2022年7月 Go教学课程 018-分支结构之switch
Switch在一些计算机语言中是保留字,其作用大多情况下是进行判断选择。以Go语言来说,switch(开关语句)常和case default一起使用。
愚公搬代码
2022/08/01
4620
【愚公系列】2022年7月 Go教学课程 018-分支结构之switch
Go-控制流语句-switch(一)
Go 语言中的 switch 控制流语句用于根据一个表达式的值,从多个可能的选项中选择一个执行。它的基本语法如下:
堕落飞鸟
2023/04/20
2870
Go-函数高级使用-条件分支-包管理-for循环-switch语句-数组及切片-与或非逻辑符
1)通常情况下,包名就是文件夹,在同一个文件夹下的 go 文件,文件里的包名必须一致
suwanbin
2019/12/12
9330
Go-函数高级使用-条件分支-包管理-for循环-switch语句-数组及切片-与或非逻辑符
第18节 switch语句
switch是一个条件语句,它计算表达式并将其与可能匹配的列表进行比较,并根据匹配执行代码块。它可以被认为是一种惯用的方式来写多个if else子句。
小尘哥
2019/07/19
6080
厚土Go学习笔记 | 14. switch 的条件写的有点灵活,不过风格还是go的一贯风格
switch是很容易理解的,先来个代码,运行起来,看看你的操作系统是什么吧。 package main import ( "fmt" "runtime" ) func main() { fmt.Print("Go runs on ") switch os := runtime.GOOS; os { case "darwin": fmt.Println("OS X.") case "linux": fmt.Println(
李海彬
2018/03/19
6740
厚土Go学习笔记 | 14. switch 的条件写的有点灵活,不过风格还是go的一贯风格
一文熟悉 Go 的分支结构(if - else-if - else、switch)
分支结构是结构化程序设计中的基础。针对分支结构,Go 提供了两种语句形式,一种是 if,另一种是 switch。
陈明勇
2023/10/15
2960
一文熟悉 Go 的分支结构(if - else-if - else、switch)
【Go 基础篇】Go语言分支结构:掌握 if 和 switch,灵活控制程序逻辑
在编程中,分支结构是一种重要的控制流程,它允许程序根据不同的条件选择不同的执行路径。Go语言提供了两种主要的分支结构:if 和 switch,用于在程序中实现条件判断和多重选择。本篇博客将深入探讨Go语言中的if和switch分支结构,帮助读者更好地理解如何使用这两种结构来控制程序逻辑流程,以及在实际编程中的应用。
繁依Fanyi
2023/10/12
2380
【Go 基础篇】Go语言分支结构:掌握 if 和 switch,灵活控制程序逻辑
11.Go语言-流程控制
所谓流程控制就是指“程序怎么执行”或者说“程序执行的顺序”。程序整体上确实是从上往下执行,但又不单纯是从上往下。
面向加薪学习
2022/09/04
5460
GO语言基础之条件语句switch
switch 是一个条件语句,用于将表达式的值与可能匹配的选项列表进行比较,并根据匹配情况执行相应的代码块。它可以被认为是替代多个if else子句的常用方式。
墨紫羽墨
2022/01/03
4180
Go语言中的控制结构:条件语句和循环
在编程中,控制结构是指引导程序如何执行的一系列指令。Go语言提供了多种控制结构来处理条件判断和循环操作。本文将详细介绍Go语言中的条件语句和循环结构,通过实例和代码解释,帮助读者全面理解和应用这些基本构造。
数字扫地僧
2024/06/12
1440
005.golang 控制语句
判断语句if 条件表达式没有括号 支持一个初始化表达式(可以是并行方式) 左大括号必须和条件语句或else在同一行 支持单行模式 初始化语句中的变量为block级别,同时隐藏外部同名变量 package main import ( "fmt" ) func main() { a := 10 b := 20 //条件表达式没有括号 //支持一个初始化表达式(可以是并行方式) if a, b := 1, 2; a > 0 { //左大括号必须和条件语句或el
qubianzhong
2018/08/02
3110
005.golang 控制语句
[GO语言基础] 五.顺序控制语句和条件控制语句(if、else、switch)
作为网络安全初学者,会遇到采用Go语言开发的恶意样本。因此从今天开始从零讲解Golang编程语言,一方面是督促自己不断前行且学习新知识;另一方面是分享与读者,希望大家一起进步。前文介绍了Golang的运算,包括算术运算、逻辑运算、赋值运算、位运算及编程练习。这篇文章将详细讲解顺序控制语句和条件控制语句。这系列文章入门部分将参考“尚硅谷”韩顺平老师的视频和书籍《GO高级编程》,详见参考文献,并结合作者多年的编程经验进行学习和丰富,且看且珍惜!后续会结合网络安全进行GO语言实战深入,加油~
Eastmount
2021/12/03
1.7K0
[GO语言基础] 五.顺序控制语句和条件控制语句(if、else、switch)
Go语言学习系列——条件语句:if-else、switch——【坚果派-红目香薰】
if-else: 1. 条件表达式不需要括号 2. 大括号必须有,且必须在同一行 3. 支持初始化语句 4. 条件必须是布尔值 switch: 1. 不需要break语句 2. 支持多条件匹配 3. 支持无条件表达式的形式 4. fallthrough关键字用于继续执行下一个case 5. case后可以是表达式 6. default可选,位置灵活
红目香薰
2025/03/13
840
Go语言学习系列——条件语句:if-else、switch——【坚果派-红目香薰】
【GO语言卵细胞级别教程】03.条件与循环语句
注意,其中fallthrough 表示无条件执行下一个case,也就是无论下一条语句执行的是true还是false都会执行。 2. 实战:switch 后面跟变量
读懂原理
2024/02/09
1350
浅谈Go语言中如何进行流程控制
注意:Go语言规定与if匹配的左括号{必须与if和表达式放在同一行,{放在其他位置会触发编译错误。同理,与else匹配的{也必须与else写在同一行,else也必须与上一个if或else if右边的大括号在同一行。
极客运维圈
2020/04/07
3360
巨细靡遗流程控制,Go lang1.18入门精炼教程,由白丁入鸿儒,Go lang流程结构详解EP09
    流程结构就是指程序逻辑到底怎么执行,进而言之,程序执行逻辑的顺序。众所周知,程序整体都是自上由下执行的,但有的时候,又不仅仅是从上往下执行那么简单,大体上,Go lang程序的流程控制结构一共有三种:顺序结构,选择结构,循环结构。顺序结构:从上向下,逐行执行;选择结构:条件满足,某些代码才会执行,0-1次;循环结构:条件满足,某些代码会被反复的执行多次,0-N次
用户9127725
2022/09/22
2960
巨细靡遗流程控制,Go lang1.18入门精炼教程,由白丁入鸿儒,Go lang流程结构详解EP09
Go语言条件语句
Go语言的条件语句在概念和流程上与其他编程语言完全相同,因此这里不再赘述,写法上结合了Python和C++,即条件表达式不需要加括号,但仍然保留了花括号。具体例子见下:
Steve Wang
2020/12/22
5820
Go——基础(1)
最近因为又报了那边的青训,后端方向的,应该是全程使用Go语言的,所以把暑假整理的笔记拿来复习一下。然后这次应该不会全程参与,主要是探索一下自己适不适合后端的工作,就先这样吧,然后下面是笔记。
mumumu
2023/01/11
4350
6.Go流程控制
前面我们写的程序都是从第一行开始执行,一直执行到末尾,一行一行的顺序执行下来,这种执行结构叫顺序执行结构。
Devops海洋的渔夫
2022/01/17
1.4K0
6.Go流程控制
相关推荐
Golang 学习笔记-2:控制流
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文