1

私は現在、ファイルのダウンロード速度に基づいてユーザーのインターネット速度接続を決定するアプリに取り組んでいます。

@Rob が Swift で答え​​を提供した同様の質問を見つけました: iOS 8 でインターネット速度を決定する正しい方法

現在、私はSwift 3を使用しており、次のように古いSwiftから彼のコードを変換しようとしました:

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

func testDownloadSpeedWithTimout(timeout: TimeInterval, completionHandler:@escaping (_ megabytesPerSecond: Double?, _ error: NSError?) -> ())
{

    let url = URL(string: "http://www.someurl.com/file")!

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

    let configuration = URLSessionConfiguration.default
    configuration.timeoutIntervalForResource = timeout

    let session = URLSession(configuration: configuration, delegate: self, delegateQueue: nil)
    session.dataTask(with: url).resume()
}


func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data)
{
    bytesReceived! += data.count
    stopTime = CFAbsoluteTimeGetCurrent()
}

func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?)
{
    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 :

ここに画像の説明を入力

誰かがこれについて支援を提供できますか? ありがとう

4

2 に答える 2

2

コードを次のように置き換える必要があります。

class ViewController: UIViewController, URLSessionDelegate, URLSessionDataDelegate
{

override func viewDidLoad()
{
    super.viewDidLoad()

    testDownloadSpeedWithTimout(timeout: 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: TimeInterval, completionHandler:@escaping (_ megabytesPerSecond: Double?, _ error: NSError?) -> ()) {
    let url = NSURL(string: "http://www.someurl.com/file")!

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

    let configuration = URLSessionConfiguration.ephemeral
    configuration.timeoutIntervalForResource = timeout
    let session = URLSession(configuration: configuration, delegate: self, delegateQueue: nil)
    session.dataTask(with: url as URL).resume()
}

func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data)
{
    bytesReceived! += data.count
    stopTime = CFAbsoluteTimeGetCurrent()
}

func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?)
{
    let elapsed = stopTime - startTime
    guard elapsed != 0 && (error == nil || ((error! as NSError).domain == NSURLErrorDomain && error?._code == NSURLErrorTimedOut)) else{
        speedTestCompletionHandler(nil, error as? NSError)
        return
    }

    let speed = elapsed != 0 ? Double(bytesReceived) / elapsed / 1024.0 / 1024.0 : -1
    speedTestCompletionHandler(speed, error as? NSError)
}
}
于 2016-12-17T07:51:57.160 に答える
0

エラー 1

Errorは Swift 3 のプロトコルです。これErrorTypeは Swift 2 の です。プロパティdomainは の一部ですNSError

URLSessionTaskが常に関数に a を渡すNSErrorかどうかは 100% わかりませんがdidCompleteWithError、そうだと思います。errorasをキャストしてNSError、成功するかどうかを確認できます。

エラー 2 および 3

エラーメッセージは誤解を招くようです。しかし、 の宣言を見たときにspeedTestCompletionHandler、引数ラベルを使用してはならないことに気付きました。_関数パラメーターの前にあるということは、パラメーター ラベルを省略しなければならないことを意味します。代わりに、次のように呼び出す必要がありますspeedTestCompletionHandler()

speedTestCompletionHandler(nil, error)
...
speedTestCompletionHandler(speed, nil)
于 2016-12-17T08:00:30.033 に答える