- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我从我的 watch 向我的 iOS 应用程序发送命令。目前尚不清楚原因,但如果应用程序在后台运行,我会看到一些错误:
Error Domain=NSURLErrorDomain Code=-997 “失去与后台传输服务的连接”
无法结束 BackgroundTask:不存在标识符为 383 (0x17f) 的后台任务,或者它可能已经结束。中断 UIApplicationEndBackgroundTaskError() 进行调试。
我已经尝试将我的配置更改为后台,为我的配置设置正确的标识符。我的 SessionManager 的静态或惰性实现。对进程进行 deinit 计数。
网络 session 管理器
static var sessionManager: SessionManager = {
let configuration = URLSessionConfiguration.background(withIdentifier: UUID().uuidString + ".WatchOS_Background")
configuration.httpShouldSetCookies = false
configuration.httpMaximumConnectionsPerHost = 4
configuration.timeoutIntervalForRequest = 50
configuration.networkServiceType = .background
configuration.isDiscretionary = false
configuration.shouldUseExtendedBackgroundIdleMode = true
if #available(iOS 13.0, *) {
configuration.allowsExpensiveNetworkAccess = true
configuration.allowsConstrainedNetworkAccess = true
}
let sessionManager = Alamofire.SessionManager(configuration: configuration)
sessionManager.delegate.sessionDidBecomeInvalidWithError = { _, error in
if let error = error {
print(error)
}
}
sessionManager.delegate.taskDidComplete = { _, task, error in
if let error = error {
print(error)
}
}
return sessionManager
}()
请求示例
func getListFromServer(completion: @escaping (ServiceResponse<[Model1]>) -> Void) {
let header: HTTPHeaders = ["User-Agent": UserAgentHelper.fullUserAgentString]
request("/api/1/XXXX", method: .get, parameters: nil, encoding: nil, headers: header).responseData { [weak self] response in
guard let strongSelf = self else { return }
completion(strongSelf.completionResponse(response))
}
}
请求方式
@discardableResult private func request(
_ path: String,
method: HTTPMethod,
parameters: Parameters? = nil,
encoding: ParameterEncoding? = nil,
headers: HTTPHeaders? = nil)
-> DataRequest {
let userEncoding = encoding ?? self.defaultEncoding
let task = beginBackgroundTask()
let dataRequest = NetworkService.sessionManager.request("\(API)\(path)",
method: method,
parameters: parameters,
encoding: userEncoding,
headers: headers)
dataRequest.validate()
self.endBackgroundTask(taskID: task)
return dataRequest
}
开始和结束后台任务
func beginBackgroundTask() -> UIBackgroundTaskIdentifier {
return UIApplication.shared.beginBackgroundTask(withName: "Background_API", expirationHandler: {})
}
func endBackgroundTask(taskID: UIBackgroundTaskIdentifier) {
UIApplication.shared.endBackgroundTask(taskID)
}
我希望从您那里得到一个正确的实现和一个稳定的请求生命周期。
非常感谢您的帮助,对于缺少技术术语,我们深表歉意。
最佳答案
您的核心问题是您没有正确处理后台任务的到期。您必须明确结束任务在其过期处理程序中:
let task = UIApplication.shared.beginBackgroundTask(withName: "Background_API") {
UIApplication.shared.endBackgroundTask(task)
}
我建议你阅读更多 here ,其中 Apple DTS 工程师广泛概述了后台任务处理的要求和边缘情况。
此外,Alamofire 并不真正支持后台 session 。使用带有后台任务处理的前台 session 可能是您最好的选择。一旦 Alamofire SessionManager
被取消初始化,它启动的任何请求都将被取消,即使是后台 session 也是如此。
最后,在 Alamofire 响应处理程序中调用 validate()
是无效的。您应该在添加响应处理程序之前根据请求调用它,因为它会在调用处理程序之前验证响应。如果您之后调用它,它将无法将它产生的错误传递给您的响应处理程序。
关于ios - 如何在 iOS 后台从 Alamofire 获得稳定的连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58558695/
我是一名优秀的程序员,十分优秀!