web-dev-qa-db-ja.com

NSURLSessionでタスクを見つけてキャンセルする方法は?

アプリケーションに画像をロードするためにNSURLSessionオブジェクトを使用しています。それは同時に複数の画像をロードする可能性があります。

特定の画像の読み込みをキャンセルして、他の画像の読み込みを続ける必要がある場合があります。

それを行う正しい方法を提案できますか?

16

タスクリストを取得するには、NSURLSessionのメソッドを使用できます

- (void)getTasksWithCompletionHandler:(void (^)(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks))completionHandler;

セッション内のすべての未処理のデータ、アップロード、ダウンロードタスクを使用して、完了コールバックを非同期に呼び出します。

次に、task.originalRequest.URLキャンセルしたいタスクを見つけるために返されたタスク。

29
Avt

以下のコードのヘルプを願っています。

-(IBAction)cancelUpload:(id)sender {    
    if (_uploadTask.state == NSURLSessionTaskStateRunning) {
        [_uploadTask cancel];
     }
  }
6
annu

Swift 3.0バージョンの@ Avt'sタスクリストを取得するための回答。 getTasksWithCompletionHandler を使用します。

func getTasksWithCompletionHandler(_ completionHandler: @escaping ([URLSessionDataTask], 
   [URLSessionUploadTask], 
   [URLSessionDownloadTask]) -> Void) {     
}

返される配列には、セッション内で作成したタスクが含まれます。完了、失敗、またはキャンセルされた後に無効にされたタスクは含まれません。

5
pedrouan

以下のすべての回答に基づいて、私はこのようなものに行きます:

Swift 5

 func cancelTaskWithUrl(_ url: URL) {
    URLSession.shared.getAllTasks { tasks in
      tasks
        .filter { $0.state == .running }
        .filter { $0.originalRequest?.url == url }.first?
        .cancel()
    }
  }

また、タスクをキャンセルすると、その完了ハンドラでErrorが発生するため、タスクの完了ハンドラも考慮する必要があります。

1
inokey

2つの方法をお勧めします。

  1. NSURLSessionTaskのリストを配列に入れます。取得する画像の数が正確にわからない場合。それをキャンセルするには、セッションのインデックスを知っている必要があります。
  2. 画像の数が限られている場合。 NSURLSessionTaskのセットをグローバル変数として使用するだけで、クラスのどこにでもアクセスしてキャンセルできます。
1
Nhon Nguyen

私はあなたがこれをするべきだと思います...

まず、xibごとにリクエストを追跡します

var download_requests = [NSURLSession]()

次に、リクエストを行うたびに、そのように配列にリクエストを追加します。

let s = NSURLSession(configuration: NSURLSessionConfiguration.defaultSessionConfiguration())
if let url = NSURL(string: "http://my.url.request.com")
{
  download_requests.append(s)
  s.dataTaskWithURL(url)
  { (data, resp, error) -> Void in
    // ....
  }
}

次に、未解決の要求をキャンセルしたいときはいつでも(viewDidDisappearで言ってみましょう)、次のようにします。

  override func viewDidDisappear(animated: Bool)
  {
    super.viewDidDisappear(animated)
    //stop all download requests
    for request in download_requests
    {
      request.invalidateAndCancel()
    }
  }
0