What is the best way to make download speed test app using swift3?

1.8k Views Asked by At

I'm using the code below snapped from this question Right way of determining internet speed in iOS 8 to make speed test in my app but when make a test and compare with the speed test tool http://www.speedtest.net/ the result of my app is less than the speedTest.net by half if my app speed result 1mbps the speedtest.net result is 2mbps or more

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?) -> ())!

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)
}

}
2

There are 2 best solutions below

0
Mohammed Saleh On BEST ANSWER

I put my file in different servers and each one give me different result so the problem is the speed result depends on the server the you download from and the solution is to have file in multi servers and detect the best server for the client and download from it.

2
Janusz On

Your code seems to test speed using single thread and that may be one of the main reasons why it measures lower results.

Speedtest.net and most of the testers such us ours as well use multithreaded approach. This is a better way to estimate capacity of the internet link.

You can find iOS SDK which will perform multi-threaded measurement here:

https://github.com/speedchecker/speedchecker-sdk-ios