来自后台推送的后台网络调用
Background Network Call from Background Push
我有一个与 Apple Watch 通信的应用程序。当主 iOS 应用程序收到远程通知时,它会使用 URLSession
触发网络请求,然后将结果发送到手表。
问题是,当 iOS 应用程序在后台并收到推送通知时,永远不会进行网络调用。我可以看到,通过断点,代码被执行了,但接收到数据时的代码没有被执行。
我确实设置了内容可用标志,我也尝试过使用 URLSessionConfiguration.background
但没有成功。
var config:URLSessionConfiguration!
var session:URLSession?
private func configureSession()
{
self.config = URLSessionConfiguration.background(withIdentifier: "backgroundFetch")
//self.config = URLSessionConfiguration.default
self.config.sessionSendsLaunchEvents = true
self.config.timeoutIntervalForRequest = 15.0
self.config.timeoutIntervalForResource = 15.0
self.session = URLSession(configuration: self.config, delegate: self, delegateQueue: nil)
}
你可以在上面看到我在默认和后台模式下都试过了。
func getCoordinatesForID(_ trackID:String, withPassCode passCode:String, andMyID myID:String)
{
let url = self.WEB_DOMAIN+"getcoord"
let hash = SecurityModel.sha256(myID+trackID+passCode)!
var request = URLRequest(url: URL(string: url)!)
request.httpMethod = "POST"
request.setValue("application/x-www-form-urlencoded;charset=utf-8", forHTTPHeaderField: "Content-Type")
let postDataStr = "auth=\(hash)&id=\(myID)&trk=\(trackID)&code=\(passCode)"
let requestBodyData = postDataStr.data(using: String.Encoding.utf8)
request.httpBody = requestBodyData
let postDataTask = self.session!.dataTask(with: request)
postDataTask.taskDescription = "getCoordinates"
postDataTask.resume()
}
上述函数是在后台调用的,但事情到此为止。什么也没有收到。在前台工作正常。
我确实实现了以下在后台时都不会调用的方法。
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data)
和
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?)
更新:
根据 Edward 的评论,我确实更新了功能以包括 "background fetch",尽管有关在通知后下载的文档并未表明这是必要的。这似乎奏效了,但只是部分奏效,因此问题仍然存在。
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?)
正在调用上面的代码但抛出错误:"Lost connection to background transfer service"
。在后台状态而非前台状态下 100% 的时间发生。
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data)
我需要并在上面的方法之前首先调用的上面,根本没有被调用。所以总体上事情已经取得了一些进展,但仍然没有像在前台时那样工作。
解法:
解决方案是删除 timeoutIntervalForRequest
和 timeoutIntervalforResource
尽管事实上我从来没有等到我设置的 15 秒才出现问题,删除这些允许进程在后台正常工作.此外,我可以使用标准 URLSessionConfiguration.default
而不是 .background。
所以最后添加 "background fetch" 功能并删除超时解决了问题。
经过对上述想法的更多测试后,我发现事情并没有始终如一地运作。问题是我使用的是 URLSessionDataTask
,事实证明,后台不支持它。根据 Apple 的文档:
Data tasks request a resource, returning the server’s response as one
or more NSData objects in memory. They are supported in default,
ephemeral, and shared sessions, but are not supported in background
sessions.
为了解决这个问题,我必须创建一个 URLSessionDownloadTask
并使用其关联的委托
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL)
当应用程序处于后台时,通过上述网络调用可以正常工作。
我有一个与 Apple Watch 通信的应用程序。当主 iOS 应用程序收到远程通知时,它会使用 URLSession
触发网络请求,然后将结果发送到手表。
问题是,当 iOS 应用程序在后台并收到推送通知时,永远不会进行网络调用。我可以看到,通过断点,代码被执行了,但接收到数据时的代码没有被执行。
我确实设置了内容可用标志,我也尝试过使用 URLSessionConfiguration.background
但没有成功。
var config:URLSessionConfiguration!
var session:URLSession?
private func configureSession()
{
self.config = URLSessionConfiguration.background(withIdentifier: "backgroundFetch")
//self.config = URLSessionConfiguration.default
self.config.sessionSendsLaunchEvents = true
self.config.timeoutIntervalForRequest = 15.0
self.config.timeoutIntervalForResource = 15.0
self.session = URLSession(configuration: self.config, delegate: self, delegateQueue: nil)
}
你可以在上面看到我在默认和后台模式下都试过了。
func getCoordinatesForID(_ trackID:String, withPassCode passCode:String, andMyID myID:String)
{
let url = self.WEB_DOMAIN+"getcoord"
let hash = SecurityModel.sha256(myID+trackID+passCode)!
var request = URLRequest(url: URL(string: url)!)
request.httpMethod = "POST"
request.setValue("application/x-www-form-urlencoded;charset=utf-8", forHTTPHeaderField: "Content-Type")
let postDataStr = "auth=\(hash)&id=\(myID)&trk=\(trackID)&code=\(passCode)"
let requestBodyData = postDataStr.data(using: String.Encoding.utf8)
request.httpBody = requestBodyData
let postDataTask = self.session!.dataTask(with: request)
postDataTask.taskDescription = "getCoordinates"
postDataTask.resume()
}
上述函数是在后台调用的,但事情到此为止。什么也没有收到。在前台工作正常。
我确实实现了以下在后台时都不会调用的方法。
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data)
和
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?)
更新:
根据 Edward 的评论,我确实更新了功能以包括 "background fetch",尽管有关在通知后下载的文档并未表明这是必要的。这似乎奏效了,但只是部分奏效,因此问题仍然存在。
func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?)
正在调用上面的代码但抛出错误:"Lost connection to background transfer service"
。在后台状态而非前台状态下 100% 的时间发生。
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data)
我需要并在上面的方法之前首先调用的上面,根本没有被调用。所以总体上事情已经取得了一些进展,但仍然没有像在前台时那样工作。
解法:
解决方案是删除 timeoutIntervalForRequest
和 timeoutIntervalforResource
尽管事实上我从来没有等到我设置的 15 秒才出现问题,删除这些允许进程在后台正常工作.此外,我可以使用标准 URLSessionConfiguration.default
而不是 .background。
所以最后添加 "background fetch" 功能并删除超时解决了问题。
经过对上述想法的更多测试后,我发现事情并没有始终如一地运作。问题是我使用的是 URLSessionDataTask
,事实证明,后台不支持它。根据 Apple 的文档:
Data tasks request a resource, returning the server’s response as one or more NSData objects in memory. They are supported in default, ephemeral, and shared sessions, but are not supported in background sessions.
为了解决这个问题,我必须创建一个 URLSessionDownloadTask
并使用其关联的委托
func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL)
当应用程序处于后台时,通过上述网络调用可以正常工作。