0

ウォッチアプリをバックグラウンドモードで実行しようとしています。WKRefreshBackgroundTaskが機能しません

https://developer.apple.com/library/content/samplecode/WatchBackgroundRefresh/Listings/WatchBackgroundRrefresh_WatchKit_Extension_MainInterfaceController_swift.html#//apple_ref/doc/uid/TP40017295-WatchBackgroundRrefresh_WatchKit_Extension_MainInterfaceController_swift-DontLinkElementID_10

しかし、それは全く機能していない。これをやって起動するために、私はこのリンゴのガイドから例をコピーしました。これは私のコードです:

import WatchKit 
import Foundation 

class InterfaceController: WKInterfaceController, WKExtensionDelegate, URLSessionDownloadDelegate { 

@IBOutlet var unlink: WKInterfaceLabel! 

@IBAction func startActivity() { 
    // fire in 20 seconds 
    let fireDate = Date(timeIntervalSinceNow: 20.0) 
    // 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.") 
     } 
    } 
} 

let sampleDownloadURL = URL(string: "http://devstreaming.apple.com/videos/wwdc/2015/802mpzd3nzovlygpbg/802/802_designing_for_apple_watch.pdf?dl=1")! 

// MARK: WKInterfaceController 

override func awake(withContext context: Any?) { 
    super.awake(withContext: context) 

    // Configure interface objects here. 
    WKExtension.shared().delegate = self 
    updateDateLabel() 
} 

let sampleDownloadURL = URL(string: "http://devstreaming.apple.com/videos/wwdc/2015/802mpzd3nzovlygpbg/802/802_designing_for_apple_watch.pdf?dl=1")! 

// MARK: WKExtensionDelegate 
func handle(_ backgroundTasks: Set<WKRefreshBackgroundTask>) { 
    for task : WKRefreshBackgroundTask in backgroundTasks { 
     print("received background task: ", task) 
     // only handle these while running in the background 
     if (WKExtension.shared().applicationState == .background) { 
      if task is WKApplicationRefreshBackgroundTask { 
       // this task is completed below, our app will then suspend while the download session runs 
       print("application task received, start URL session") 
       scheduleURLSession() 
      } 
     } 
     else if let urlTask = task as? WKURLSessionRefreshBackgroundTask { 
      let backgroundConfigObject = URLSessionConfiguration.background(withIdentifier: urlTask.sessionIdentifier) 
      let backgroundSession = URLSession(configuration: backgroundConfigObject, delegate: self, delegateQueue: nil) 

      print("Rejoining session ", backgroundSession) 
     } 
     // make sure to complete all tasks, even ones you don't handle 
     task.setTaskCompleted() 
    } 
} 

// MARK: Snapshot and UI updating 

func scheduleSnapshot() { 
    // fire now, we're ready 
    let fireDate = Date() 
    WKExtension.shared().scheduleSnapshotRefresh(withPreferredDate: fireDate, userInfo: nil) { error in 
     if (error == nil) { 
      print("successfully scheduled snapshot. All background work completed.") 
     } 
    } 
} 

func updateDateLabel() { 
    let currentDate = Date() 
    self.unlink.setHidden(false) 
    unlink.setText(dateFormatter.string(from: currentDate)) 
} 

// MARK: URLSession handling 

func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) { 
    print("NSURLSession finished to url: ", location) 
    updateDateLabel() 
    scheduleSnapshot() 
} 

func scheduleURLSession() { 
    let backgroundConfigObject = URLSessionConfiguration.background(withIdentifier: NSUUID().uuidString) 
    backgroundConfigObject.sessionSendsLaunchEvents = true 
    let backgroundSession = URLSession(configuration: backgroundConfigObject) 

    let downloadTask = backgroundSession.downloadTask(with: sampleDownloadURL) 
    downloadTask.resume() 
} 

} 

それは、正常にスケジュールバックグラウンドタスクを印刷し、バックグラウンドにアプリを送信し、ハンドルを待つために王冠を使用します。BackgroundTasksはを発射し、その後、私はバックグラウンドにアプリを送ったがハンドルメソッドに決して入力しないでください。

助けてください!ありがとうございました!!!

答えて

0

私はAppleのどちらかの例を得られませんでした。しかし、私はバックグラウンドリフレッシュを次のコードで処理しました。 Appleの例とは異なり、バックグラウンドセッションでは自分自身を代理人にする必要があることに注意してください。 (また、あなたは本当にスウィフトで "自己"を必要としません、私はプロパティ/機能を示すためにここでそれを使用しています)。 didCompleteWithErrorエラー:MSのように私はdownloadTask叩く前:プリント/ブレークポイント私は時々仕事を打ったことなく、また

var backgroundUrlSession:URLSession? 
var pendingBackgroundURLTask:WKURLSessionRefreshBackgroundTask? 

func handle(_ backgroundTasks: Set<WKRefreshBackgroundTask>) { 

    for task in backgroundTasks { 
     if let refreshTask = task as? WKApplicationRefreshBackgroundTask { 
      // this task is completed below, our app will then suspend while the download session runs 
      print("application task received, start URL session") 

      if let request = self.getRequestForRefresh() { 
       let backgroundConfig = URLSessionConfiguration.background(withIdentifier: NSUUID().uuidString) 
       backgroundConfig.sessionSendsLaunchEvents = true 
       backgroundConfig.httpAdditionalHeaders = ["Accept":"application/json"] 
       //Be sure to set self as delegate on this urlSession 
       let urlSession = URLSession(configuration: backgroundConfig, delegate: self, delegateQueue: nil) 
       let downloadTask = urlSession.downloadTask(with: request) 

       print("Dispatching data task at \(self.getTimestamp())") 
       downloadTask.resume() 
      } 
      self.scheduleNextBackgroundRefresh(refreshDate: self.getNextPreferredRefreshDate()) 
      refreshTask.setTaskCompleted() 
     } 
     else if let urlTask = task as? WKURLSessionRefreshBackgroundTask   
     { 
      //awakened because background url task has completed 
      let backgroundConfigObject = URLSessionConfiguration.background(withIdentifier: urlTask.sessionIdentifier) 
      //Be sure to set self as delegate on this urlSession 
      self.backgroundUrlSession = URLSession(configuration: backgroundConfigObject, delegate: self, delegateQueue: nil) //set to nil in task:didCompleteWithError: delegate method 

      print("Rejoining session ", self.backgroundUrlSession as Any) 
      self.pendingBackgroundURLTask = urlTask //Saved for .setTaskComplete() in downloadTask:didFinishDownloadingTo location: (or if error non nil in task:didCompleteWithError:) 

     } else { 
      //else different task, not handling but must Complete all tasks (snapshot tasks hit this logic) 
      task.setTaskCompleted() 
     } 
    } 
} 

func getRequestForRefresh() -> URLRequest? { 

    guard let url = URL(string: "https://pokeapi.co/api/v2/pokemon") else{ 
     return nil 
    } 

    return URLRequest(url: url) 
} 

// MARK: URLSession handling 

func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) { 
    print("NSURLSession finished to url: ", location) 
    updateDateLabel() 
    scheduleSnapshot() 

    self.pendingBackgroundURLTask.setTaskCompleted() 
    self.backgroundUrlSession = nil 
} 

func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { 
    if error != nil { 
     self.pendingBackgroundURLTask.setTaskCompleted() 
     self.backgroundUrlSession = nil 
    } 
} 

didFinishDownloadingTo場所を:.

代わりに、私はdownloadTask:didFinishDownloadingTo場所で完了したself.pendingBackgroundURLTaskを設定しました。私はタスク:didCompleteWithErrorエラーで完了しました:もしエラー!= nil。私はこのロジックを含むように私の答えを更新しました。

これがあなたを助けてくれることを願っています。それは私たちのために生産で働いています。

+0

私は、この2つの関数(*** getRequestForRefresh()***と*** scheduleNextBackgroundRefresh()***)とこの2つの変数の*初期化*のコードを教えてください。*** backgroundUrlSession ***と*** pendingBackgroundURLTask ***) – ainovela

+0

私はそれらを初期化せず、代わりにそれらをオプションとして宣言します。私はgetRequestForRefresh()を共有することはできませんが、あなたのコードで何をするかを示すために私の答えを更新します。 scheduleNextBackgrounRefresh()メソッドは、WKExtension.shared()を呼び出します。scheduleBackgroundRefresh(withPreferredDate:startActivityメソッドと同じですが、次に計算された日時で更新を試みる必要があります。 WKApplicationRefreshBackgroundTaskの設定を完了してください)。 – CodenameDuchess

関連する問題