我正在处理复杂问题以从Web服务获取计划数据。每20-30分钟(或手动),我正在安排WKRefreshBackgroundTask来执行此操作。
正如Apple建议的那样,我希望操作系统通过后台NSURLSession
来处理这些数据的获取。
这是我用来下载我需要的数据的功能:
func scheduleURLSession()
{
print("\nScheduling URL Session...")
let backgroundSessionConfig:URLSessionConfiguration = URLSessionConfiguration.background(withIdentifier: NSUUID().uuidString)
backgroundSessionConfig.sessionSendsLaunchEvents = true
let backgroundSession = URLSession(configuration: backgroundSessionConfig)
let downloadTask = backgroundSession.downloadTask(with: URL(string: "https://www.myserver.com/somedata")!)
downloadTask.resume()
}
关于此的一些事情:
问题是,即使我在任务上调用resume()
并允许它在完成时唤醒我的应用程序,但它似乎也没有。
完成后,它应该回到WKExtensionDelegate处理程序:
func handle(_ backgroundTasks: Set<WKRefreshBackgroundTask>)
作为WKURLSessionRefreshBackgroundTask
,但事实并非如此。
我的代码与Apple的示例代码相同,然后创建另一个会话,但通过WKURLSessionRefreshBackgroundTask
标识符重新加入。这是设置委托以处理下载数据的位置。检查代码:
func handle(_ backgroundTasks: Set<WKRefreshBackgroundTask>) {
for task in backgroundTasks {
switch task {
case let backgroundTask as WKApplicationRefreshBackgroundTask:
print("\nWatchKit - WKApplicationRefreshBackgroundTask")
// self.updateComplicationDataArrivalTimes(backgroundTask)
self.scheduleURLSession()
backgroundTask.setTaskCompleted()
case let snapshotTask as WKSnapshotRefreshBackgroundTask:
// Snapshot tasks have a unique completion call, make sure to set your expiration date
print("\nWatchKit - WKSnapshotRefreshBackgroundTask")
snapshotTask.setTaskCompleted(restoredDefaultState: true, estimatedSnapshotExpiration: Date.distantFuture, userInfo: nil)
case let connectivityTask as WKWatchConnectivityRefreshBackgroundTask:
print("\nWatchKit - WKWatchConnectivityRefreshBackgroundTask")
connectivityTask.setTaskCompleted()
case let urlSessionTask as WKURLSessionRefreshBackgroundTask:
print("\nWatchKit - WKURLSessionRefreshBackgroundTask")
let backgroundConfigObject = URLSessionConfiguration.background(withIdentifier: urlSessionTask.sessionIdentifier)
let backgroundSession = URLSession(configuration: backgroundConfigObject, delegate: self, delegateQueue: nil)
print("Rejoining session ", backgroundSession)
urlSessionTask.setTaskCompleted()
default:
// make sure to complete unhandled task types
task.setTaskCompleted()
}
}
}
但同样,它似乎永远不会回来。尽管代码与Apple的此项目示例代码相同,但我似乎无法弄清楚为什么这样做有效:WatchBackgroundRefresh: Using WKRefreshBackgroundTask to update WatchKit apps in the background。
我的项目中是否有一些我不知道的设置?我将所有这些代码放在watch {3}中的ExtensionDelegate
新内容中。我也符合WKExtensionDelegate
和URLSessionDownloadDelegate
。
提前感谢您的帮助!
答案 0 :(得分:4)
我从来没有让Apple的例子工作,但我确实得到了后台刷新功能。与他们的示例不同,您需要使自己成为会话的代表。因此,请改为创建这样的后台会话:
让backgroundSession = URLSession(配置:backgroundSessionConfig,delegate:self,delegateQueue:nil)
我在这里有详细的代码示例(请参阅问题代码):
WatchOS 3 WKApplicationRefreshBackgroundTask didReceiveChallenge
希望它有所帮助。
答案 1 :(得分:4)
我搞定了!我开始时通过观察WWDC&#39; 16视频/笔记,将它们与Apple的WatchBackgroundRefresh示例进行比较。然后,在浏览Apple Dev论坛时,我找到了this thread,遇到了同样的问题。在那里,一个人,&#34; Daniel Fontes&#34;发布他的食谱&#39;让它工作(注意,不是接受的答案!),并结合视频为我工作。
我为使Apple示例工作做了什么:
var savedTask:WKRefreshBackgroundTask?
handle( backgroundTasks:)
函数中,将WKURLSessionRefreshBackgroundTask
保存到局部变量self.savedTask = task
- 不要task.setTaskCompleted()(!!)urlSession - didFinishDownloading:
中,在您阅读收到的数据后,将已保存的任务设置为已完成:self.savedTask?.setTaskCompleted()
。希望这可以提供帮助!
PS。这适用于模拟器(xcode 8.3.3,watchOS 3.2)