iOS后台运行机制-实践总结

  从2015年,接触到的项目里,就会有这样的需求:APP需要像Android那样,在后台状态下,执行正常的功能。到现在已经一年多了吧,一直在研究这个方面,写下一些心得,希望与大家共同交流探讨。

  首先,我们要知道,苹果对APP占用硬件资源管的很严,更不要说应用后台时候的资源占用了。正常情况下,使用应用时,APP从硬盘加载到内存,开始工作;当用户按下home键,APP便被挂起,依然驻留在内存中,这种状态下,不调用苹果已开放的几种后台方法,程序便不会运行;如果在这个时候,使程序继续运行,则为后台状态;如果当前内存将要不够用时,系统会自动把之前挂起状态下的APP请出内存。所以我们看到,有些时候打开APP时,还是上次退出时的那个页面那些数据,有时则是重新从闪屏进入。

  这样,就知道了后台运行最大的前置条件——APP处于内存中的挂起状态。

  然后,再来看看上面说到的苹果已开放的后台运行方法。先看这张图

  

  很明显,我们项目里能用的机制就这么多,Background Audio,这是后台的音频,这个很早之前便有,可以实现后台的声音播放。去年的项目里用它在后台一直播放没有声音的文件,结果审核失败。

  在这里说一下去年做的那个项目的需求,用户类型A可以在任何时刻查看用户类型B的地理位置。这个功能有点像iPhone上的『查找朋友』,不知道的朋友请自行了解(想知道你的朋友在哪里吗,想知道你的另一半在哪里吗,对了,就用它);A想看B的时候,B需要上传自己的当前位置给服务器;先不考虑APP在挂起状态怎么做,先说APP在活动状态下,服务器想和客户端进行通信,告诉客户端要上传自己的位置了,这种服务器主动通信,常用到的就是socket和推送通知。我决定用推送,在APP收到来自APNS的推送时,就进行定位并上传。

  然而,按下home键进入挂起状态时,程序是不会执行的,所以也获取不到B的位置。BOSS大为恼火,Android分分钟干完的事,你怎么就搞不定呢(脑补:再搞不出来就滚蛋)。

  当时第一次接触苹果这些后台机制,探索之路弯弯曲曲,就不一一表述了。最后用静默推送解决了这个问题:Remote Notification!原理非常简单,不过苹果的初衷不是让我这样用的……,说一下这个机制的应用场景:以往聊天类应用接受推送后点进去需要再收一次信息,这情况在QQ、微信等应用上最为明显。不过拥有了这个接口后,这情况将不复存在,以后推送将能够直接启动后台任务,在后台就已经接收到信息,点开APP不需要去拉取。

  so,在A查看B位置的时候,给B一条静默推送,B在后台定位并上传信息。这个唤起时间比较短,在3-5秒左右,有时候B网络不好,没有上传成功就又被挂起了,就需要重复进行。这个机制添加方法和推送一样,只有一点区别,就是委托方法不同。普通推送会执行这个回调:

1 - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
2
3     DDLogDebug(@"[普通推送]%@", userInfo);
4 }

  而勾选住上面那个推送唤醒,就会回调这个方法:

1 - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
2     DDLogDebug(@"[后台推送]%@", userInfo);
3     completionHandler(UIBackgroundFetchResultNewData);
4 }

  可以在这个回调里,调用定位请求之类的。

  本以为解决了问题,BOSS试了,也觉得可以。就喜滋滋的等着升职加薪走上人生巅峰,咳咳,又做梦了。

  "咋么回事呃,现在又定不到位了,赶紧搞好"还没到两个小时,BOSS气呼呼的跑过来喷了一顿。说完之后的0.01秒,我就知道是怎么回事了,"听我解释啊,老板"还没说出口,他就摔门而出,留下欲哭无泪的我。只有两个原因,一、APP被人为上划kill掉;二、APP被系统回收了,kill 了。

  就酱,明知山有虎,偏向虎山行。为了不让系统回收APP,我非常强硬的,加上了Background Audio。结果可想而知,被拒绝的同时,收到一封英文邮件,问我为什么这样做,如有异议,可提出。哎,总算松了一口气,可以离职了(个人原因)。

  换了公司,需求也不一样了,APP需要每五秒和服务器进行一次数据交换;以下,用到的是VoIP。

  刚开始的时候,推送唤醒机制还可以,不过林子大了什么鸟都有,一样的型号一样的设置,有台iPhone就是唤醒不了,只能尝试新方法。想起QQ语音时,切到后台依然可以通话,我想,就是它了。VoIP:后台语音服务,类似Skype通话应用需要调用,可进行后台的语音通话。既然是语音通话,那么肯定是常连接,于是,有了以下代码。

 1 @implementation NSStream(StreamsToHost)
 2
 3 + (void)getStreamsToHostNamed:(NSString *)hostName
 4                          port:(UInt32)port
 5                   inputStream:(out __strong NSInputStream **)inputStreamPtr
 6                  outputStream:(out __strong NSOutputStream **)outputStreamPtr
 7 {
 8     CFReadStreamRef     readStream;
 9     CFWriteStreamRef    writeStream;
10
11     assert(hostName != nil);
12     assert( (port > 0) && (port < 65536) );
13     assert( (inputStreamPtr != NULL) || (outputStreamPtr != NULL) );
14
15     readStream = NULL;
16     writeStream = NULL;
17
18     CFStreamCreatePairWithSocketToHost(
19                                        NULL,
20                                        (__bridge CFStringRef) hostName,
21                                        port,
22                                        ((inputStreamPtr  != NULL) ? &readStream : NULL),
23                                        ((outputStreamPtr != NULL) ? &writeStream : NULL)
24                                        );
25
26     if (inputStreamPtr != NULL) {
27         *inputStreamPtr  = CFBridgingRelease(readStream);
28     }
29
30     if (outputStreamPtr != NULL) {
31         *outputStreamPtr = CFBridgingRelease(writeStream);
32     }
33 }
34
35 @end

  给NSStream加了一个类目。然后还需要一个server,我就不写了;发起连接请求让客户端与server保持通信,这些代码也太多了,就不贴了。勾选Voice over IP后,APP挂起状态时,系统会接管socket会话句柄,当收到从server发来的数据流时,就会唤起APP进入后台执行代码。这个唤起时间要长一些,可以在十秒多点。已经测试成功,但是还没有提交审核,还需要给它一个外套,不然就像上次一样被拒绝。

  一直在探索,因为以上方法并不完美,而且项目对后台的要求比较苛刻,事实上,用户在使用APP时,会有很多场景,最常见的就是弱网络,在这个场景下,不管是推送还是socket都无法收到内容,所以像这种需要依赖外力唤起的方式,弊端还是相当明显。

  已经感觉到后面写的比较仓促,VoIP涉及的内容还是比较多,还没有一一吃透,还是心急了些。个人知识有限,如有错误,欢迎指正。

  

时间: 2024-08-27 08:23:54

iOS后台运行机制-实践总结的相关文章

IOS后台运行机制 与 动作

当用户按下"Home"键或者系统启动另外一个应用时,前台foreground应用首先切换到Inactive状态,然后切换到Background状态.此转换将会导致先后调用应用代理的applicationWillResignActive:和applicationDidEnterBackground:方法. 在applicationDidEnterBackground:方法返回后,大部分应用在之后不久转入suspended状态.对于请求特定后台background任务的应用,比如播放音乐应

iOS后台运行机制简解

1.iOS其实是伪后台 为什么说iOS是伪后台?首先需要了解一下iOS中的后台进程到底是怎么回事.iOS中所谓的“后台驻留”并不是指执行中的程序,而是指最近使用过的程序.当我们是一个进程进入到后台的时候,可以想象成是Command+Tab键盘. 一般来说,当把一个app退到后台的时候都会有5s的时间执行缓冲,有些程序可以要求达到10分钟(这个是需要开发人员来决定的),因此在按下Home键之后,本来的程序就会退到后台中去,最多10分钟之后还是会被终止的,这当然和苹果的后台管理机制有关.   2.i

ios后台运行机制

IOS长时间后台运行的实现代码 1.检查设备是否支持多任务 Apple出于性能的考虑,并不是所有的iOS设备升级到iOS4以后都支持多任务,比如iPhone 3G.如果你的应用在没有多任务特性时会出问题,为了保持应用的健壮性,你应该对此进行判断并处理.你可以通过调用UIDevice对象的multitaskingSupported属性来获取当前设备是否支持多任务. [cpp] view plaincopy if(![UIDevicecurrentDevice].multitaskingSuppor

iOS 后台运行实现

iOS 后台运行的规则 应用的运行状态分为以下五种:Not running:应用还没有启动,或者应用正在运行但是途中被系统停止.Inactive:当前应用正在前台运行,但是并不接收事件(当前或许正在执行其它代码).一般每当应用要从一个状态切换到另一个不同的状态时,中途过渡会短暂停留在此状态.唯一在此状态停留时间比较长的情况是:当用户锁屏时,或者系统提示用户去响应某些(诸如电话来电.有未读短信等)事件的时候.Active:当前应用正在前台运行,并且接收事件.这是应用正在前台运行时所处的正常状态Su

ios后台传输机制

http://www.appcoda.com/background-transfer-service-ios7/ http://www.raywenderlich.com/51127/nsurlsession-tutorial https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/URLLoadingSystem/Articles/UsingNSURLSession.html ios后台传输机制

iOS 后台运行 类型

iOS后台运行,需要有特定的类型才可以进行.这些内容并不是一直不变的,苹果也在逐步的更新这些内容. 本文内容是2015年11月03日时苹果支持的后台运行类型. 这是官方连接地址 其中较为重要的是下面这张表,我已截图出来. 解释一下: 1. 音频播放和录制: 2. 位置更新: 3. VOIP: *4. 后台下载(此处指预更新): 5. 使用External Accessory framework库(通常是通过MFI认证的蓝牙应用): 6. 蓝牙应用(使用Core Bluetooth framewo

IOS 后台运行申请更多的时间

当应用程序进入后台时,系统会自动回调应用程序委托的applicationDidEnterBackground:方法. 应用可以在该方法中完成转入后台前需要做的准备工作,所有的应用需要做以下事情. 释放所有可以释放的内存. 保存用户数据或状态信息,所有没写入磁盘的文件或信息,在进入后台之前,都应该写入磁盘,因为程序可能在后台被杀死. 进入后台时释放内存 当程序进入后台之后,为了确保获得最佳的用户体验,建议释放那些占用内存较大且可以重新获取的资源—- 这是因为当应用处于后台时,iOS系统会优先终止那

iOS后台运行

我从苹果文档中得知,一般的应用在进入后台的时候可以获取一定时间来运行相关任务,也就是说可以在后台运行一小段时间.还有三种类型的可以运行在后以,1.音乐2.location3.voip 文二 在IOS后台执行是本文要介绍的内容,大多数应用程序进入后台状态不久后转入暂停状态.在这种状态下,应用程序不执行任何代码,并有可能在任意时候从内存中删除.应用程序提供特定的服务,用户可以请求后台执行时间,以提供这些服务. 判断是否支持多线程 UIDevice* device = [UIDevice curren

IOS后台运行浅析

在之前的文章<App States and Multitasking IOS应用程序状态和多任务>说到IOS程序有前台后台之分.在IOS程序进入后台之后,程序就会不执行代码,如果非要有什么必须执行的过程,可以申请大约600s的时间,如果在这段时间内程序还没有完成则会被系统杀死.出现:has active assertions beyond permitted time. 更多IOS后台内容参考:<IOS7 Background Fetch后台应用程序刷新> <IOS 7四种后