Swift WatchOS后台提取

Swift WatchOS后台提取,swift,watchos,Swift,Watchos,我在开发WatchOS应用程序时遇到了以下问题 我开发了一个Apple WatchOS扩展,它从API获取数据并显示这些数据。不过,我还想让手表在后台提取数据。在Xcode模拟器中,这工作得非常好。5分钟的间隔按预期工作 然而,在物理设备上,这似乎根本不起作用,或者在非常随机的时间内也不起作用。例如,下午4:00的计划刷新将在下午4:48或更晚时间触发 extensionelegate.swift 出于此示例目的,URLSession不是现有端点 class ExtensionDelegate:

我在开发WatchOS应用程序时遇到了以下问题

我开发了一个Apple WatchOS扩展,它从API获取数据并显示这些数据。不过,我还想让手表在后台提取数据。在Xcode模拟器中,这工作得非常好。5分钟的间隔按预期工作

然而,在物理设备上,这似乎根本不起作用,或者在非常随机的时间内也不起作用。例如,下午4:00的计划刷新将在下午4:48或更晚时间触发

extensionelegate.swift

出于此示例目的,URLSession不是现有端点

class ExtensionDelegate: NSObject, WKExtensionDelegate, URLSessionTaskDelegate {
func applicationDidFinishLaunching() {
    // Perform any final initialization of your application.
    
    // Example scheduling of background task an hour in the future
    WKExtension.shared().scheduleBackgroundRefresh(withPreferredDate: Date(timeIntervalSinceNow: 5.0 * 60.0), userInfo: nil) { (error: Error?) in
        if let error = error {
            print("Error occured while scheduling background refresh: \(error.localizedDescription)")
        }
    }
}

func applicationDidBecomeActive() {
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}

func applicationWillResignActive() {
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, etc.
}

func handle(_ backgroundTasks: Set<WKRefreshBackgroundTask>) {
    // Sent when the system needs to launch the application in the background to process tasks. Tasks arrive in a set, so loop through and process each one.
    for task in backgroundTasks {
        // Use a switch statement to check the task type
        switch task {
        case let backgroundTask as WKApplicationRefreshBackgroundTask:
            // Be sure to complete the background task once you’re done.
            beginDownloadTask()
            backgroundTask.setTaskCompleted()
        case let snapshotTask as WKSnapshotRefreshBackgroundTask:
            // Snapshot tasks have a unique completion call, make sure to set your expiration date
            snapshotTask.setTaskCompleted(restoredDefaultState: true, estimatedSnapshotExpiration: Date.distantFuture, userInfo: nil)
        case let connectivityTask as WKWatchConnectivityRefreshBackgroundTask:
            // Be sure to complete the connectivity task once you’re done.
            connectivityTask.setTaskCompleted()
        case let urlSessionTask as WKURLSessionRefreshBackgroundTask:
            // Be sure to complete the URL session task once you’re done.
            urlSessionTask.setTaskCompleted()
        default:
            // make sure to complete unhandled task types
            task.setTaskCompleted()
        }
    }
}

func beginDownloadTask() {
    let config = URLSessionConfiguration.background(withIdentifier: "exampleSessionIdentifier")
    let session = URLSession(configuration: config, delegate: self, delegateQueue: nil)
    let task = session.downloadTask(with: URL(string: "http://www.example.com/data")!)
    task.resume()
}

func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
    print("Session did complete")
    WKExtension.shared().scheduleBackgroundRefresh(withPreferredDate: Date(timeIntervalSinceNow: 1.0 * 60.0), userInfo: nil) { (error: Error?) in
        if let error = error {
            return print("Error occured while scheduling background refresh: \(error.localizedDescription)")
        }
        print("Scheduled")
    }
}
}
类extensionelegate:NSObject、wkextensionelegate、URLSessionTaskDelegate{
func applicationdFinishLaunching(){
//执行应用程序的任何最终初始化。
//未来一小时后台任务调度示例
WKExtension.shared().scheduleBackgroundRefresh(使用PreferredDate:Date(timeIntervalSinceNow:5.0*60.0),userInfo:nil){(错误:error?)在
如果let error=error{
打印(“安排后台刷新时出错:\(Error.localizedDescription)”)
}
}
}
func applicationIDbecomeactive(){
//重新启动应用程序处于非活动状态时暂停(或尚未启动)的所有任务。如果应用程序以前位于后台,可以选择刷新用户界面。
}
func applicationWillResignActive(){
//当应用程序即将从活动状态移动到非活动状态时发送。这可能发生在某些类型的临时中断(如来电或短信)或用户退出应用程序并开始转换到后台状态时。
//使用此方法暂停正在进行的任务、禁用计时器等。
}
func句柄(uuBackgroundTasks:Set){
//当系统需要在后台启动应用程序来处理任务时发送。任务以集合的形式到达,因此循环并处理每个任务。
用于背景任务中的任务{
//使用switch语句检查任务类型
切换任务{
案例let backgroundTask作为WKApplicationRefreshBackgroundTask:
//完成后,确保完成后台任务。
beginDownloadTask()
backgroundTask.setTaskCompleted()已完成
案例让snapshotTask作为WKSnapshotRefreshBackgroundTask:
//快照任务具有唯一的完成调用,请确保设置过期日期
snapshotTask.setTaskCompleted(restoredDefaultState:true,estimatedSnapshotExpiration:Date.distantFuture,userInfo:nil)
案例let connectivityTask as wkWatch connectivityRefreshBackgroundTask:
//完成后,请确保完成连接任务。
connectivityTask.setTaskCompleted()
案例让urlSessionTask作为WKURLSessionRefreshBackgroundTask:
//完成后,请确保完成URL会话任务。
urlSessionTask.setTaskCompleted()已完成
违约:
//确保完成未处理的任务类型
task.setTaskCompleted()已完成
}
}
}
func beginDownloadTask(){
让config=URLSessionConfiguration.background(带有标识符:“exampleSessionIdentifier”)
let session=URLSession(配置:config,委托:self,委托队列:nil)
let task=session.downloadTask(带URL(字符串):http://www.example.com/data")!)
task.resume()
}
func urlSession(uSession:urlSession,task:URLSessionTask,DidCompleteWither错误:错误?){
打印(“会话已完成”)
WKExtension.shared().scheduleBackgroundRefresh(使用PreferredDate:Date(timeIntervalSinceNow:1.0*60.0),userInfo:nil){(错误:error?)在
如果let error=error{
返回打印(“安排后台刷新时出错:\(Error.localizedDescription)”)
}
打印(“预定”)
}
}
}