ios - Swift下载速度说明

标签 ios swift networking download

我想使用这个 question 的代码答案因为这正是我要找的。但是我不能使用我不太了解的东西。

谁能给我解释一下这段代码是如何计算下载速度的?

class ViewController: UIViewController, NSURLSessionDelegate, NSURLSessionDataDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()

        testDownloadSpeedWithTimout(5.0) { (megabytesPerSecond, error) -> () in
            print("\(megabytesPerSecond); \(error)")
        }
    }

    var startTime: CFAbsoluteTime!
    var stopTime: CFAbsoluteTime!
    var bytesReceived: Int!
    var speedTestCompletionHandler: ((megabytesPerSecond: Double?, error: NSError?) -> ())!

    /// Test speed of download
    ///
    /// Test the speed of a connection by downloading some predetermined resource. Alternatively, you could add the
    /// URL of what to use for testing the connection as a parameter to this method.
    ///
    /// - parameter timeout:             The maximum amount of time for the request.
    /// - parameter completionHandler:   The block to be called when the request finishes (or times out).
    ///                                  The error parameter to this closure indicates whether there was an error downloading
    ///                                  the resource (other than timeout).
    ///
    /// - note:                          Note, the timeout parameter doesn't have to be enough to download the entire
    ///                                  resource, but rather just sufficiently long enough to measure the speed of the download.

    func testDownloadSpeedWithTimout(timeout: NSTimeInterval, completionHandler:(megabytesPerSecond: Double?, error: NSError?) -> ()) {
        let url = NSURL(string: "http://insert.your.site.here/yourfile")!

        startTime = CFAbsoluteTimeGetCurrent()
        stopTime = startTime
        bytesReceived = 0
        speedTestCompletionHandler = completionHandler

        let configuration = NSURLSessionConfiguration.ephemeralSessionConfiguration()
        configuration.timeoutIntervalForResource = timeout
        let session = NSURLSession(configuration: configuration, delegate: self, delegateQueue: nil)
        session.dataTaskWithURL(url).resume()
    }

    func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData) {
        bytesReceived! += data.length
        stopTime = CFAbsoluteTimeGetCurrent()
    }

    func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) {
        let elapsed = stopTime - startTime
        guard elapsed != 0 && (error == nil || (error?.domain == NSURLErrorDomain && error?.code == NSURLErrorTimedOut)) else {
            speedTestCompletionHandler(megabytesPerSecond: nil, error: error)
            return
        }

        let speed = elapsed != 0 ? Double(bytesReceived) / elapsed / 1024.0 / 1024.0 : -1
        speedTestCompletionHandler(megabytesPerSecond: speed, error: nil)
    }

}

最佳答案

底部函数是 URLSession 完成下载时的委托(delegate)回调。速度计算在此函数的倒数第二行完成:

        let speed = elapsed != 0 ? Double(bytesReceived) / elapsed / 1024.0 / 1024.0 : -1

这就是说,如果耗时不为 0,则取接收到的总字节数除以经过的秒数(计算方法是用开始时间减去 session: dataTask 的时间: didReceiveData: 调用上面的委托(delegate)方法)。然后除以 1024.0 两次以从字节 -> 兆字节开始。否则,它返回 -1。

关于ios - Swift下载速度说明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39663688/

相关文章:

ios - 在 objective-c 中更改电话号码的颜色(UITextView ...在 xib 文件中启用检测电话号码)

ios - 返回 NSString 时如何解决不兼容的 block 指针类型编译器错误?

networking - Go网络编程库

shell - 无法使用exec在Go中为docker运行netstat

iphone - 适用于 IOS 的 XML 解析器 SDK

ios - didReceiveRemoteNotification :fetchCompletionHandler: but the completion handler was never called

ios - 将 NSManagedObjectContext 传递给函数时使用 inout 关键字?

php - 使用 Swift 启动 PHP

ios - 如何向另一个类中的 UIButton 添加操作

iphone - 创建 TCP 套接字连接并在多个 View 中保持连接打开