Progress of a Alamofire request

17,592

Solution 1

The way you monitor progress in Alamofire is using the progress closure on a Request. More details on usage can be found in the README. While that example in the README demonstrates usage on a download request, it still works on a data request as well.

The one important note is that you do not always get perfect reporting back from the server for a data request. The reason is that the server does not always report an accurate content length before streaming the data. If the content length is unknown, the progress closure will be called, but the totalExpectedBytesToRead will always be -1.

In this situation, you can only report accurate progress if you know the approximate size of the data being downloaded. You could then use your approximate number in conjunction with the totalBytesRead value to compute an estimated download progress value.

Solution 2

Alamofire 4.0 and Swift 4.x

func startDownload(audioUrl:String) -> Void {
    let fileUrl = self.getSaveFileUrl(fileName: audioUrl)
    let destination: DownloadRequest.DownloadFileDestination = { _, _ in
        return (fileUrl, [.removePreviousFile, .createIntermediateDirectories])
    }

    Alamofire.download(audioUrl, to:destination)
        .downloadProgress { (progress) in
            self.surahNameKana.text = (String)(progress.fractionCompleted)
        }
        .responseData { (data) in
            // at this stage , the downloaded data are already saved in fileUrl
            self.surahNameKana.text = "Completed!"
    }
}

Solution 3

To make a download with progress for Swift 2.x users with Alamofire >= 3.0:

let url = "https://httpbin.org/stream/100" // this is for example..
let destination = Alamofire.Request.suggestedDownloadDestination(directory: .DocumentDirectory, domain: .UserDomainMask)

Alamofire.download(.GET, url, parameters: params, encoding: ParameterEncoding.URL,destination:destination)
                .progress { bytesRead, totalBytesRead, totalBytesExpectedToRead in
                    // This closure is NOT called on the main queue for performance
                    // reasons. To update your ui, dispatch to the main queue.         
                    dispatch_async(dispatch_get_main_queue()) {
                        // Here you can update your progress object
                        print("Total bytes read on main queue: \(totalBytesRead)")
                        print("Progress on main queue: \(Float(totalBytesRead) / Float(totalBytesExpectedToRead))")
                    }
                }
                .response { request, _, _, error in
                    print("\(request?.URL)")  // original URL request
                    if let error = error {
                        let httpError: NSError = error
                        let statusCode = httpError.code
                    } else { //no errors
                        let filePath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0]
                        print("File downloaded successfully: \(filePath)")
                    }
            }
Share:
17,592
vinbhai4u
Author by

vinbhai4u

Crazy for mobile development When I am free you can find me under a book or watching TV Series

Updated on July 28, 2022

Comments

  • vinbhai4u
    vinbhai4u over 1 year

    Will it be possible to show progress for

    Alamofire.request(.POST, URL, parameters: parameter, encoding: .JSON)
     .responseJSON { response in
     // Do your stuff
    }
    

    I get my images/documents as a base64 string then I convert it as files in mobile

    Can I show a progress bar with percentage?

    I am using Alamofire, Swift 2

  • vinbhai4u
    vinbhai4u over 8 years
    as I understand, I cannot show an progress for .request rite?
  • cnoon
    cnoon over 8 years
    Depends on the type of data you are getting back. For example, if you download image data from something like S3 using request, you will probably be able to accurately report the progress because the server will tell you what the totalExpectedBytes is. If you are hitting a JSON web service that computes the response on-the-fly, it may not compute how large the response will be before sending it back. In that case you would NOT be able to accurately report progress.
  • vinbhai4u
    vinbhai4u over 8 years
    I am using the later one, I think. So I think its best to show a loader and then wait till the request is completed Thanks for your help @cnoon
  • cnoon
    cnoon over 8 years
    You bet dude. If you think the answer is sufficient, then you should upvote and mark as the answer. 👍🏼
  • Daniyar
    Daniyar over 7 years
    @cnoon is there a way to use already loaded part of data in the progress handler?
  • Saeed Rahmatolahi
    Saeed Rahmatolahi over 6 years
    I used progress in alert and want to use this in the alamo fire but didn't work for me here is the link of that stackoverflow.com/questions/46070516/…