从我的手表,我发送命令到我的iOS应用程序。不清楚原因,但如果应用程序在后台,我可以看到一些错误:
Error Domain=NSURLErrorDomain Code=-997 "Lost connection to background transfer service"
Can't end BackgroundTask: no background task exists with identifier 383 (0x17f), or it may have already been ended. Break in UIApplicationEndBackgroundTaskError() to debug.
我已经尝试将配置更改为后台,请为我的配置提供正确的标识符。
我的SessionManager的静态或延迟实现。
计算进程中的deinit。
网络会话管理器

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并不真正支持后台会话。在后台任务处理中使用前台会话可能是最好的选择。一旦AlamofireSessionManager被取消初始化,它启动的任何请求都将被取消,即使是后台会话。
最后,在Alamofire响应处理程序中调用validate()是无效的。您应该在添加响应处理程序之前对请求调用它,因为它在调用处理程序之前验证响应。如果您在之后调用它,它将无法将它产生的错误传递给您的响应处理程序。

10-08 16:59