前言
iOS12版本后,AFNetworking请求过程中,app返回后台,会出现以下错误,并且网络请求中断(只在真机中出现,模拟器不会复现)
HTTP load failed (error code: 53 [1:53])
2018-08-30 11:54:43.390749+0200 Background[2224:809685] Task <7CD7B0DD-2CE2-400D-AC02-D66C0F4E4847>.<7> finished with error - code: 53
2018-08-30 11:54:43.391271+0200 Background[2224:809125] Task <7CD7B0DD-2CE2-400D-AC02-D66C0F4E4847>.<7> load failed with error Error Domain=NSPOSIXErrorDomain Code=53 "Software caused connection abort" UserInfo={_NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <7CD7B0DD-2CE2-400D-AC02-D66C0F4E4847>.<7>, _kCFStreamErrorDomainKey=1, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"LocalDataTask <7CD7B0DD-2CE2-400D-AC02-D66C0F4E4847>.<7>"
), _kCFStreamErrorCodeKey=53} [53]
failure The operation couldn’t be completed. Software caused connection abort
处理
此情况产生原因是苹果iOS12系统后台挂起逻辑更换了导致,苹果承诺在iOS13修复这个问题,但看情况应该不会修复
所以我们这边对这种情况进行处理,主要是在AppDelegate上:
OC版:
@property (nonatomic, unsafe_unretained) UIBackgroundTaskIdentifier taskId;
@property (nonatomic, strong) NSTimer *timer;
- (void)applicationDidEnterBackground:(UIApplication *)application {
// 这个判断是为了防止进入后台之后时间还没过完进入前台又开启了新的任务导致APP被强制kill掉
if(self.taskId != UIBackgroundTaskInvalid){
return;
}
self.taskId =[application beginBackgroundTaskWithExpirationHandler:^(void) {
//当申请的后台时间用完的时候调用这个block
//此时我们需要结束后台任务,
[self endTask];
}];
// 模拟一个长时间的任务 Task
self.timer =[NSTimer scheduledTimerWithTimeInterval:1.0f
target:self
selector:@selector(longTimeTask:)
userInfo:nil
repeats:YES];
}
#pragma mark - 停止timer
-(void)endTask
{
if (_timer != nil||_timer.isValid) {
[_timer invalidate];
_timer = nil;
//结束后台任务
[[UIApplication sharedApplication] endBackgroundTask:_taskId];
_taskId = UIBackgroundTaskInvalid;
// NSLog(@"停止timer");
}
}
- (void) longTimeTask:(NSTimer *)timer{
// 系统留给的我们的时间
NSTimeInterval time =[[UIApplication sharedApplication] backgroundTimeRemaining];
NSLog(@"系统留给的我们的时间 = %.02f Seconds", time);
}
swift版:
var backgroundTask: UIBackgroundTaskIdentifier = .invalid
func applicationWillResignActive(_ application: UIApplication) {
backgroundTask = UIApplication.shared.beginBackgroundTask { [weak self] in
self?.endBackgroundTask()
}
}
func endBackgroundTask() {
print("Background task ended.")
UIApplication.shared.endBackgroundTask(backgroundTask)
backgroundTask = .invalid
}