设备休眠时发出 Alamofire 请求
Alamofire requests while device is sleeping
我的 iOS 应用程序从我们的主要服务接收通知以刷新其状态。现在,我们正在使用 Alamofire 获取最新状态,并在有更新数据时播放持续的声音。我们的设备锁定在引导模式以阻止它们关闭并提供信息亭体验。
我们正在进行更改,以便设备可以在 xx 分钟不活动后进入睡眠状态。但是,我们 运行 遇到了一个问题,即使请求已成功发送(基于我们在 api 端的日志),设备也无法从 Alamofire 获取结果。
因为我使用的是 Alamofire 4,所以我已经使用 backgroundsessionmanager
设置了一个单例,这就是现在发送 AF 请求的方式。但挑战在于,请求是间歇性发送的,并且在设备休眠时大部分时间都会失败,并出现此错误:
Domain=NSURLErrorDomain Code=-997 "Lost connection to background transfer service"
这是我的单例代码(我在 AppDelegate 中有相关代码):
class Networking {
static let sharedInstance = Networking()
public var sessionManager: Alamofire.SessionManager // most of your web service clients will call through sessionManager
public var backgroundSessionManager: Alamofire.SessionManager // your web services you intend to keep running when the system backgrounds your app will use this
private init() {
self.sessionManager = Alamofire.SessionManager(configuration: URLSessionConfiguration.default)
self.backgroundSessionManager = Alamofire.SessionManager(configuration: URLSessionConfiguration.background(withIdentifier: "com.test.app"))
}
}
这是我发送请求的代码:
let NetworkManager = Networking.sharedInstance.backgroundSessionManager
DispatchQueue.main.async(execute: {
NetworkManager.request(self.api_url, method: .post, parameters: params, encoding: JSONEncoding.default, headers: headers).responseJSON{ response in
switch (response.result){
case .success:
if let jsonResp = response.result.value{
print("got the response")
print(jsonResp)
// parse results
}
case .failure:
print("Network Error: \(response.error)")
}
}
})
我希望得到一些帮助来解决这个问题,因为我无法找出不一致行为的根本原因。我在某些地方读到 Apple/iOS 只允许 upload/download 当应用程序处于后台模式而不是 requests
。
是的,后台会话只允许上传和下载任务,不允许数据任务。它们也只允许基于委托的请求,而不是基于完成处理程序的请求。 This answer 概述了结合 Alamofire 执行此操作时的许多注意事项。
但这引出了一个问题,即您是否真的想要使用后台会话。当您的应用程序被唤醒以进行后台获取时,如果您能够在合理的时间内(例如 30 秒)完成您的请求,您可能应该考虑使用标准会话,而不是后台会话。简单多了。
不要将“背景”中的应用程序 运行 与“背景”URLSessionConfiguration
混为一谈:它们是完全不同的模式。仅仅因为您的应用程序在后台 运行,并不意味着您必须使用后台 URLSessionConfiguration
。如果您的应用程序是 运行(无论是在前台还是在后台),那么标准会话就可以了。如果您希望它在应用程序暂停(或终止)后继续运行,并且您愿意承担后台会话带来的所有额外开销,则只需要后台会话。
后台会话不适用于应用程序在后台 运行 时执行的请求。它们适用于在您的应用程序暂停后仍将继续的请求(即使它最终在其自然生命周期中终止)。这意味着后台会话非常适合无法在合理时间内完成的缓慢请求,例如下载视频资产、下载许多大型图像资产或文档等。
但是,如果您只是执行例行 GET/POST 请求,该请求将在合理的时间内完成,请考虑不使用后台 URLSessionConfiguration
,而只执行正常请求并调用后台提取请求完成时的完成处理程序(即在网络请求的完成处理程序中)。
我的 iOS 应用程序从我们的主要服务接收通知以刷新其状态。现在,我们正在使用 Alamofire 获取最新状态,并在有更新数据时播放持续的声音。我们的设备锁定在引导模式以阻止它们关闭并提供信息亭体验。
我们正在进行更改,以便设备可以在 xx 分钟不活动后进入睡眠状态。但是,我们 运行 遇到了一个问题,即使请求已成功发送(基于我们在 api 端的日志),设备也无法从 Alamofire 获取结果。
因为我使用的是 Alamofire 4,所以我已经使用 backgroundsessionmanager
设置了一个单例,这就是现在发送 AF 请求的方式。但挑战在于,请求是间歇性发送的,并且在设备休眠时大部分时间都会失败,并出现此错误:
Domain=NSURLErrorDomain Code=-997 "Lost connection to background transfer service"
这是我的单例代码(我在 AppDelegate 中有相关代码):
class Networking {
static let sharedInstance = Networking()
public var sessionManager: Alamofire.SessionManager // most of your web service clients will call through sessionManager
public var backgroundSessionManager: Alamofire.SessionManager // your web services you intend to keep running when the system backgrounds your app will use this
private init() {
self.sessionManager = Alamofire.SessionManager(configuration: URLSessionConfiguration.default)
self.backgroundSessionManager = Alamofire.SessionManager(configuration: URLSessionConfiguration.background(withIdentifier: "com.test.app"))
}
}
这是我发送请求的代码:
let NetworkManager = Networking.sharedInstance.backgroundSessionManager
DispatchQueue.main.async(execute: {
NetworkManager.request(self.api_url, method: .post, parameters: params, encoding: JSONEncoding.default, headers: headers).responseJSON{ response in
switch (response.result){
case .success:
if let jsonResp = response.result.value{
print("got the response")
print(jsonResp)
// parse results
}
case .failure:
print("Network Error: \(response.error)")
}
}
})
我希望得到一些帮助来解决这个问题,因为我无法找出不一致行为的根本原因。我在某些地方读到 Apple/iOS 只允许 upload/download 当应用程序处于后台模式而不是 requests
。
是的,后台会话只允许上传和下载任务,不允许数据任务。它们也只允许基于委托的请求,而不是基于完成处理程序的请求。 This answer 概述了结合 Alamofire 执行此操作时的许多注意事项。
但这引出了一个问题,即您是否真的想要使用后台会话。当您的应用程序被唤醒以进行后台获取时,如果您能够在合理的时间内(例如 30 秒)完成您的请求,您可能应该考虑使用标准会话,而不是后台会话。简单多了。
不要将“背景”中的应用程序 运行 与“背景”URLSessionConfiguration
混为一谈:它们是完全不同的模式。仅仅因为您的应用程序在后台 运行,并不意味着您必须使用后台 URLSessionConfiguration
。如果您的应用程序是 运行(无论是在前台还是在后台),那么标准会话就可以了。如果您希望它在应用程序暂停(或终止)后继续运行,并且您愿意承担后台会话带来的所有额外开销,则只需要后台会话。
后台会话不适用于应用程序在后台 运行 时执行的请求。它们适用于在您的应用程序暂停后仍将继续的请求(即使它最终在其自然生命周期中终止)。这意味着后台会话非常适合无法在合理时间内完成的缓慢请求,例如下载视频资产、下载许多大型图像资产或文档等。
但是,如果您只是执行例行 GET/POST 请求,该请求将在合理的时间内完成,请考虑不使用后台 URLSessionConfiguration
,而只执行正常请求并调用后台提取请求完成时的完成处理程序(即在网络请求的完成处理程序中)。