Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/110.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 后台的URLSessionDownloadTask从不触发WKURLSession​;刷新&x200B;背景&x200B;任务_Ios_Watchkit_Apple Watch_Nsurlsessiondownloadtask_Watchos 3 - Fatal编程技术网

Ios 后台的URLSessionDownloadTask从不触发WKURLSession​;刷新&x200B;背景&x200B;任务

Ios 后台的URLSessionDownloadTask从不触发WKURLSession​;刷新&x200B;背景&x200B;任务,ios,watchkit,apple-watch,nsurlsessiondownloadtask,watchos-3,Ios,Watchkit,Apple Watch,Nsurlsessiondownloadtask,Watchos 3,试图理解为什么在WatchKit 3.0中安排后台URLSessionDownloadTask时。func句柄(u backgroundTasks:Set)从不为WKURLSession激发​刷新​背景​任务,但其他任务也会执行,如WKApplicationRefreshBackgroundTask和WKSnapshotRefreshBackgroundTask 手表中的我的代码extensionelegate func applicationDidBecomeActive() { //

试图理解为什么在WatchKit 3.0中安排后台URLSessionDownloadTask时。func
句柄(u backgroundTasks:Set)
从不为
WKURLSession激发​刷新​背景​任务
,但其他任务也会执行,如
WKApplicationRefreshBackgroundTask
WKSnapshotRefreshBackgroundTask

手表中的我的代码
extensionelegate

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.

    scheduleBackgroundRefresh(in: 10)
}

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.
            scheduleURLSession()
            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: // This is never fired, Don't know why, arrrgggggg
            // Be sure to complete the URL session task once you’re done.

            let backgroundConfigObject = URLSessionConfiguration.background(withIdentifier: urlSessionTask.sessionIdentifier)
            let backgroundSession = URLSession(configuration: backgroundConfigObject, delegate: self, delegateQueue: nil) // delegate set to self here after rejoining the session

            print("Rejoining session ", backgroundSession)

            urlSessionTask.setTaskCompleted() // probably need to postpone this until the url `urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL)` has completed, but either way, this switch case is never met
        default:
            // make sure to complete unhandled task types
            task.setTaskCompleted()
        }
    }
}

func scheduleURLSession() {
    if let url = URL(string: "https://some.path.com") {
        let backgroundConfigObject = URLSessionConfiguration.background(withIdentifier: NSUUID().uuidString)
        let backgroundSession = URLSession(configuration: backgroundConfigObject, delegate: nil, delegateQueue: nil) // nil delegate here because delegate is "supposed" to be set in `handle(_ backgroundTasks:)` delegate method ("Rejoining session"). 

        let task = backgroundSession.downloadTask(with: url)
        task.resume()
    } else {
        print("Url error")
    }
}

func scheduleBackgroundRefresh(in seconds: TimeInterval) {
    let fireDate = Date(timeIntervalSinceNow: seconds)
    // optional, any SecureCoding compliant data can be passed here
    let userInfo = ["reason" : "background update"] as NSDictionary

    WKExtension.shared().scheduleBackgroundRefresh(withPreferredDate: fireDate, userInfo: userInfo) { (error) in
        if (error == nil) {
            print("successfully scheduled background task, use the crown to send the app to the background and wait for handle:BackgroundTasks to fire.")
        }
    }
}
func applicationIDBECOMEACTIVE(){
//重新启动应用程序处于非活动状态时暂停(或尚未启动)的所有任务。如果应用程序以前位于后台,可以选择刷新用户界面。
scheduleBackgroundRefresh(in:10)
}
func句柄(uuBackgroundTasks:Set){
//当系统需要在后台启动应用程序来处理任务时发送。任务以集合的形式到达,因此循环并处理每个任务。
用于背景任务中的任务{
//使用switch语句检查任务类型
切换任务{
案例let backgroundTask作为WKApplicationRefreshBackgroundTask:
//完成后,确保完成后台任务。
scheduleURLSession()
backgroundTask.setTaskCompleted()已完成
案例让snapshotTask作为WKSnapshotRefreshBackgroundTask:
//快照任务具有唯一的完成调用,请确保设置过期日期
snapshotTask.setTaskCompleted(restoredDefaultState:true,estimatedSnapshotExpiration:Date.distantFuture,userInfo:nil)
案例let connectivityTask as wkWatch connectivityRefreshBackgroundTask:
//完成后,请确保完成连接任务。
connectivityTask.setTaskCompleted()
case让urlSessionTask作为WKURLSessionRefreshBackgroundTask://这从未被激发,不知道为什么,arrrggggg
//完成后,请确保完成URL会话任务。
让backgroundConfigObject=URLSessionConfiguration.background(标识符为urlSessionTask.sessionIdentifier)
让backgroundSession=URLSession(配置:backgroundConfigObject,委托:self,delegateQueue:nil)//重新加入会话后,委托在此处设置为self
打印(“重新加入会议”,背景会议)
urlSessionTask.setTaskCompleted()//可能需要将此操作推迟到url`urlSession(\uSession:urlSession,downloadTask:URLSessionDownloadTask,didFinishDownloadingTo location:url)`已完成,但无论如何,都不会满足此切换情况
违约:
//确保完成未处理的任务类型
task.setTaskCompleted()已完成
}
}
}
func scheduleURLSession(){
如果让url=url(字符串):https://some.path.com") {
让backgroundConfigObject=URLSessionConfiguration.background(带有标识符:nsuid().uuidString)
让backgroundSession=URLSession(配置:backgroundConfigObject,delegate:nil,delegateQueue:nil)//此处为nil delegate,因为委托“假定”是在`handle(u-backgroundTasks:)`delegate方法(“重新加入会话”)中设置的。
let task=backgroundSession.downloadTask(带:url)
task.resume()
}否则{
打印(“Url错误”)
}
}
func scheduleBackgroundRefresh(秒:时间间隔){
让fireDate=Date(时间间隔:秒)
//可选,可在此传递任何符合SecureCoding的数据
让userInfo=[“原因”:“后台更新”]作为NSDictionary
WKExtension.shared().scheduleBackgroundRefresh(使用PreferredDate:fireDate,userInfo:userInfo){(错误)在中
如果(错误==nil){
打印(“已成功安排后台任务,使用crown将应用程序发送到后台,并等待handle:BackgroundTasks启动。”)
}
}
}


你知道为什么后台的
URLSessionDownloadTask
从不触发
handle(u-backgroundTasks:Set)
触发吗?

你已经将preferredFireDate设置为10秒。正如苹果公司所说,并没有任何保证能如此迅速地启动处理方法

首选火石

下一个后台快照刷新任务的时间。系统 尽一切努力在某个时刻在后台唤醒你的应用程序 在预定时间之后,但不能保证准确的时间

当我将这个参数设置为30秒时,我不得不等待大约10分钟,直到系统调用handle方法

此外,您还必须为WKDextension设置委托

WKExtension.shared().delegate=self//self是实现handle-metod的对象

编辑

后台应用程序刷新任务已编入预算。通常,系统会为dock中的每个应用程序(包括最近使用的应用程序)大约每小时执行一项任务。此预算在dock上的所有应用程序之间共享。系统每小时为每个应用程序执行多个任务,活动手表表面会出现复杂情况。该预算由手表表面的所有复杂部件共同承担。在您耗尽预算后,系统会延迟您的请求,直到有更多的时间可用


可能是因为您的委派队列总是
nil
?如何将其设置为
OperationQueue.main