11

I have an NetworkRequest class, where all my alamofire requests made:

    class NetworkRequest {
        static let request = NetworkRequest()

        var currentRequest: Alamofire.Request?

        let dataManager = DataManager()
        let networkManager = NetworkReachabilityManager()
        let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT

        func downloadData<T: Film>(slug: String, provider: String, section: String, dynamic: String, anyClass: T, completion: ([T]?) -> Void ) {
            var token: String = ""

            if LOGGED_IN == true {
                token = "\(NSUserDefaults.standardUserDefaults().valueForKey(TOKEN)!)"
            }

            let headers = [
                "Access": "application/json",
                "Authorization": "Bearer \(token)"
            ]

            let dataUrl = "\(BASE_URL)\(slug)\(provider)\(section)\(dynamic)"
            print(headers)
            print(dataUrl)

            if networkManager!.isReachable {

                currentRequest?.cancel()

                dispatch_async(dispatch_get_global_queue(priority, 0)) {

                    if let url = NSURL(string: dataUrl) {
                        let request = Alamofire.request(.GET, url, headers: headers)

                        request.validate().responseJSON { response in
                            switch response.result {
                            case .Success:
                                if let data = response.result.value as! [String: AnyObject]! {
                                    let receivedData = self.dataManager.parseDataToFilms(data, someClass: anyClass)
                                    completion(receivedData)
                                }

                            case .Failure(let error):
                                print("Alamofire error: \(error)")

                                if error.code == 1001 {
                                    self.goToNoConnectionVC()
                                }

                                print("canceled")
                            }

                        }
                    }
                }
            } else {
                goToNoConnectionVC()
            }
        }
}

And I need to cancel previous downloadData request, when the new one starts, tried to cancel using currentRequest?.cancel(), but it doesn't help.

Already tried to cancelOperations using NSOperationsBlock, but it doesn't cancels current operation.

I block UI now, so that user can't send another request. But this is not correct, causes some errors later...

Pls, help

Ruslan Sabirov
  • 440
  • 1
  • 4
  • 19

4 Answers4

23

Now on Alamofire 4 the Alamofire.Manager.sharedInstance.session is not available you should use this solution:

let sessionManager = Alamofire.SessionManager.default 
sessionManager.session.getTasksWithCompletionHandler { dataTasks, uploadTasks, downloadTasks in 
dataTasks.forEach { $0.cancel() } 
uploadTasks.forEach { $0.cancel() } 
downloadTasks.forEach { $0.cancel() } 
}

and if you want to cancel (suspend, resume) a particular request you can check the request url in your .forEach block like this:

dataTasks.forEach {
                if ($0.originalRequest?.url?.absoluteString == url) {
                    $0.cancel()
                }
            }
Constantin Saulenco
  • 2,353
  • 1
  • 22
  • 44
2

Found needed solution:

func stopAllSessions() {
    Alamofire.Manager.sharedInstance.session.getAllTasksWithCompletionHandler { tasks in
        tasks.forEach { $0.cancel() }
    }
}

Update for Alamofire 5

func stopAllSessions() {
    AF.session.getTasksWithCompletionHandler { (sessionDataTask, uploadData, downloadData) in
        sessionDataTask.forEach { $0.cancel() }
        uploadData.forEach { $0.cancel() }
        downloadData.forEach { $0.cancel() }
    }
}
Ruslan Sabirov
  • 440
  • 1
  • 4
  • 19
1

Swift 5

To cancel all requests use

Alamofire.Session.default.session.getTasksWithCompletionHandler({ dataTasks, uploadTasks, downloadTasks in
        dataTasks.forEach { $0.cancel() }
        uploadTasks.forEach { $0.cancel() }
        downloadTasks.forEach { $0.cancel() }
    })

To cancel a request with a particular url use

Alamofire.Session.default.session.getTasksWithCompletionHandler({ dataTasks, uploadTasks, downloadTasks in
    dataTasks.forEach {
            if ($0.originalRequest?.url?.absoluteString == "www.google.com") {
                $0.cancel()
            }
        
    }
    uploadTasks.forEach {
        if ($0.originalRequest?.url?.absoluteString == "www.google.com") {
            $0.cancel()
        }
    }
    downloadTasks.forEach {
        if ($0.originalRequest?.url?.absoluteString == "www.google.com") {
            $0.cancel()
        }
        
    }
})
0

If you want to cancel the request, you need to trace the requests made and try to cancel it. You can store it in an array and cancel every previous request stored. In your code you create a request: let request = Alamofire.request(.GET, url, headers: headers) but you try to cancel the currentRequest?.cancel() that is never valued.

ciccioska
  • 1,291
  • 16
  • 22