ios - NSURLSessionDataDelegate NSURLSessionDataDelegate 函数未通过 dataTask 触发

标签 ios swift networking

我有一个类可以使用 this answer 来测量网络带宽。 我尝试使用相同的函数在 Swift 中重写该类:

class BandwidthChecker : NSObject, NSURLSessionDelegate, NSURLSessionDataDelegate {

var startTime = NSDate()
var endTime = NSDate()
var bytesReceived = 0
var completionHandler : ((speed: Double, error: ErrorType?)->Void)?;

override init() {
    super.init()
}

func testDownloadSpeeWithURL(url: NSURL, timeout: NSTimeInterval, completionHandler: (speed: Double, error: ErrorType?)->Void) {
    self.startTime = NSDate()
    self.endTime = self.startTime
    self.bytesReceived = 0
    self.completionHandler = completionHandler

    let configuration = NSURLSessionConfiguration.ephemeralSessionConfiguration()
    configuration.timeoutIntervalForResource = timeout
    configuration.timeoutIntervalForRequest = timeout

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

func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveResponse response: NSURLResponse, completionHandler: (NSURLSessionResponseDisposition) -> Void) {
    self.startTime = NSDate()
    self.endTime = self.startTime
}

func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData) {
    self.bytesReceived += data.length
    self.endTime = NSDate()
}

func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) {
    let elapsed = self.endTime.timeIntervalSinceDate(self.startTime)
    let speed = elapsed != 0 ? (Double(self.bytesReceived) / elapsed / 1024.0 / 1024.0 ) : -1

    // timeout is no error, still measure speed
    if error == nil || (error!.domain == NSURLErrorDomain && error!.code == NSURLErrorTimedOut) {
        self.completionHandler!(speed: speed, error: nil)
    } else {
        self.completionHandler!(speed: speed, error: error)
    }
}
}

我正在通过单元测试来测试这段代码(是的,它会进入“真正的”互联网,在我知道它的工作原理后我会 mock 它):

func testBandwidth() {
    let bandwithChecker = BandwidthChecker()
    let asyncExpectation = expectationWithDescription("longRunningFunction")
    var errorResult : ErrorType?
    var speedResult : Double
    speedResult = 0

    bandwithChecker.testDownloadSpeeWithURL(NSURL(string: "http://download.thinkbroadband.com/1GB.zip")!, timeout: 10, completionHandler: {(speed, error) -> Void in
        errorResult = error
        speedResult = speed
        asyncExpectation.fulfill()
    })

    self.waitForExpectationsWithTimeout(20) { error in
        XCTAssertNil(error)
        if errorResult != nil {
            XCTFail("Error while measuring bandwith")
            print("#error:",errorResult)
        } else {
            XCTAssert(speedResult>0)
            print("##### SPEED #####\n")
            print("speed: \(speedResult) MB/s\n")
            print("#################\n")
        }
    }

}

这应该在 10 秒后给我一个结果,但显然我在 20 秒后从 waitForExpectationWithTimeout 得到超时。根本未到达 didReceiveDatadidCompleteWithErrordidReceiveResponse 中的断点。

当我将测试中的网址更改为无效网址(例如“无效网址”)时,didCompleteWithError实际上会触发并给我一个无效网址错误.

此时我已经无能为力了。有人可以提示我这个问题或给我一个解决方案吗?谢谢大家,我真的很感激!

问候 j0h4nn3s

最佳答案

也许你应该尝试使用 block 来代替?

let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { (data, response, error) -> Void in
//log here to see if it gets called, and test for error
}

task?.resume()

关于ios - NSURLSessionDataDelegate NSURLSessionDataDelegate 函数未通过 dataTask 触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37857412/

相关文章:

ios - 快速拍摄黑色图像

windows - 在 Windows XP、SP3 上使用 RawCap 嗅探本地主机

ios - 如果从 App Delegate 启动,则 ViewController 显示没有导航栏

objective-c - UIButton 删除触摸覆盖边框

ios - iOS 上具有不对称形状的核心文本

sockets - 模拟本地网络的低速连接

ubuntu - PF_RING ubuntu 安装

ios fwrite 函数 EXC_BAD_ACCESS

swift - 使用 FireBase + CocoaPods 的 Google Ads 出现错误 : "duplicated symbols for architechture x86_64"

ios - 自动布局在 iPhone 6s Plus 中无法按预期工作