1

I want to get percentage of download in label. I use this code

self.percentageLabel.text = "\(Int(percentage * 100))%"

But the problem is the number showing like this ( -90043% )

Any idea ?

This my full code

import UIKit

class ViewController: UIViewController, URLSessionDownloadDelegate {

    let shapeLayer = CAShapeLayer()

    let percentageLabel: UILabel = {

        let label = UILabel()
        label.text = ""
        label.textAlignment = .center
        label.font = UIFont.boldSystemFont(ofSize: 32)
        return label
    }()


    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view, typically from a nib.

        view.addSubview(percentageLabel)
        percentageLabel.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
        percentageLabel.center = view.center

        let trackLayer = CAShapeLayer()
        let circularPath = UIBezierPath(arcCenter: .zero, radius: 100, startAngle: 0, endAngle: 2 * CGFloat.pi, clockwise: true)

        trackLayer.path = circularPath.cgPath
        trackLayer.strokeColor = UIColor.white.cgColor
        trackLayer.lineWidth = 0.2
        trackLayer.fillColor = UIColor.clear.cgColor
        trackLayer.lineCap = CAShapeLayerLineCap.round
        trackLayer.position = view.center

        view.layer.addSublayer(trackLayer)


        shapeLayer.path = circularPath.cgPath
        shapeLayer.strokeColor = UIColor.yellow.cgColor
        shapeLayer.lineWidth = 10
        shapeLayer.fillColor = UIColor.clear.cgColor
        shapeLayer.lineCap = CAShapeLayerLineCap.round
        shapeLayer.position = view.center

        shapeLayer.transform = CATransform3DMakeRotation(-CGFloat.pi/2, 0, 0, 1)

        shapeLayer.strokeEnd = 0

        view.layer.addSublayer(shapeLayer)

        view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleTap)))
    }


    let urlString = UIPasteboard.general

    private func beginDownloadingFile()
    {
        print("Downloading Started ... ")
        self.shapeLayer.strokeEnd = 0
        let configuration = URLSessionConfiguration.default
        let operationQueue = OperationQueue()
        let urlSession = URLSession(configuration: configuration, delegate: self, delegateQueue: operationQueue)
        if let urlString = urlString.string {
            print(urlString)
            guard let url = URL(string: urlString) else {
                      print("URL Not valid")
                      return

                  }

            let downloadTask = urlSession.downloadTask(with: url)
                  downloadTask.resume()
        }

         }

    func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didFinishDownloadingTo location: URL) {
        print("Finshed Downloading Files")
    }

    func urlSession(_ session: URLSession, downloadTask: URLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
        print("TotalBytes:- ", totalBytesWritten, "and toBytesWrittenExpected:- ", totalBytesExpectedToWrite)

        let percentage = Float(totalBytesWritten) / Float(totalBytesExpectedToWrite)
        print("percentage : ", percentage)


        DispatchQueue.main.async {
            self.shapeLayer.strokeEnd = CGFloat(percentage)
            self.percentageLabel.text = "\(Int(percentage * 100))%"
            self.percentageLabel.font = UIFont.boldSystemFont(ofSize: 20)
            self.percentageLabel.textColor = UIColor.white

        }

        print("Percentage Downloaded:- ", percentage)

    }

    fileprivate func animateCircle() {
        let basicAnimation = CABasicAnimation(keyPath: "strokeEnd")

        basicAnimation.toValue = 1

        basicAnimation.duration = 2

        basicAnimation.fillMode = CAMediaTimingFillMode.forwards
        basicAnimation.isRemovedOnCompletion = false

        shapeLayer.add(basicAnimation, forKey: "urSoBasic")
    }

    @objc private func handleTap(){
        print("Do Animation")

        beginDownloadingFile()

    }

}
vadian
  • 274,689
  • 30
  • 353
  • 361
BoSaif
  • 11
  • 2
  • What type is `percentage` and what its real value? – pawello2222 Jun 01 '20 at 21:29
  • let percentage = Float(totalBytesWritten) / Float(totalBytesExpectedToWrite) print("percentage : ", percentage) DispatchQueue.main.async { self.shapeLayer.strokeEnd = CGFloat(percentage) self.percentageLabel.text = "\(Int(percentage * 100))%" – BoSaif Jun 01 '20 at 21:31
  • 2
    Now where are `totalBytesWritten` and `totalBytesExpectedToWrite` coming from? Also, please edit additional details into your question instead of just posting them as a comment, especially for code - it's really hard to read. – John Montgomery Jun 01 '20 at 21:33
  • Try to debug what are `totalBytesWritten` and `totalBytesExpectedToWrite` and see if the result is as expected – pawello2222 Jun 01 '20 at 21:33
  • Am already add the full code @pawello2222 – BoSaif Jun 01 '20 at 21:35
  • When `percentage` label is equal to `-90043%` what are the values of `totalBytesWritten` and `totalBytesExpectedToWrite`? – pawello2222 Jun 01 '20 at 21:39
  • @pawello2222 [ TotalBytes:- 9453 and toBytesWrittenExpected:- -1 ] – BoSaif Jun 01 '20 at 21:41
  • Does this answer your question? [totalBytesExpectedToWrite is -1 in NSURLSessionDownloadTask](https://stackoverflow.com/questions/23585432/totalbytesexpectedtowrite-is-1-in-nsurlsessiondownloadtask) – John Montgomery Jun 01 '20 at 21:47
  • You should check if `totalBytesExpectedToWrite` is -1, and show "file size unknown" or something like that instead. Or fix the server the file is coming from, if you're able to. – John Montgomery Jun 01 '20 at 21:48

1 Answers1

1

Your code looks correct. So the problem is with the values of totalBytesWritten andtotalBytesExpectedToWrite.

If totalBytesWritten = 9453 and totalBytesExpectedToWrite = -1 then you can't calculate the percentage.

Basically you have to make sure the value passed in the totalBytesExpectedToWrite is correct.

From Apple documentation for URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:

The expected length of the file, as provided by the Content-Length header. If this header was not provided, the value is NSURLSessionTransferSizeUnknown (-1).

As suggested in the comments you can try this explanation to try solve totalBytesExpectedToWrite = -1

pawello2222
  • 46,897
  • 22
  • 145
  • 209