我有一个类可以使用 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
得到超时。根本未到达 didReceiveData
、didCompleteWithError
和 didReceiveResponse
中的断点。
当我将测试中的网址更改为无效网址(例如“无效网址”
)时,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/