我正在使用 SimplePing 来获取我的 swift 应用程序中的延迟,但我没有得到任何结果。
这是从 SO 中的示例中提取的代码:
import Foundation
public typealias SimplePingClientCallback = (String?)->()
public class SimplePingClient: NSObject {
static let singletonPC = SimplePingClient()
private var resultCallback: SimplePingClientCallback?
private var pingClinet: SimplePing?
private var dateReference: NSDate?
public static func pingHostname(hostname: String, andResultCallback callback: SimplePingClientCallback?) {
singletonPC.pingHostname(hostname, andResultCallback: callback)
}
public func pingHostname(hostname: String, andResultCallback callback: SimplePingClientCallback?) {
resultCallback = callback
pingClinet = SimplePing(hostName: hostname)
pingClinet?.delegate = self
pingClinet?.start()
}
}
extension SimplePingClient: SimplePingDelegate {
public func simplePing(pinger: SimplePing, didStartWithAddress address: NSData) {
pinger.sendPingWithData(nil)
}
public func simplePing(pinger: SimplePing, didFailWithError error: NSError) {
resultCallback?(nil)
}
public func simplePing(pinger: SimplePing!, didSendPacket packet: NSData!) {
dateReference = NSDate()
}
public func simplePing(pinger: SimplePing!, didFailToSendPacket packet: NSData!, error: NSError!) {
pinger.stop()
resultCallback?(nil)
}
public func simplePing(pinger: SimplePing, didReceiveUnexpectedPacket packet: NSData) {
pinger.stop()
resultCallback?(nil)
}
public func simplePing(pinger: SimplePing!, didReceivePingResponsePacket packet: NSData!) {
pinger.stop()
guard let dateReference = dateReference else { return }
//timeIntervalSinceDate returns seconds, so we convert to milis
let latency = NSDate().timeIntervalSinceDate(dateReference) * 1000
resultCallback?(String(format: "%.f", latency))
}
}
为了在我的 viewController 中调用 SimplePing,我这样做了:
let simplePingClient = SimplePingClient()
simplePingClient.pingHostname("www.apple.com") { latency in
print("Your latency is \(latency ?? "unknown")")
self.labelTempsReponse?.text = latency
}
当我在这一行放置断点时:
simplePingClient.pingHostname("www.apple.com") { latency in
所有结果均为零(resultCallBack、pingClient 和 dateReference)。我做了一个研究来解决这个问题,我发现了一个 question与我的相似,但在 objective-c 中。
谁能帮帮我?
最佳答案
SimplePingClient
中的签名与它尝试实现的 SimplePingDelegate
协议(protocol)不匹配。也许这些曾经在一些早期版本中匹配过,但从 Swift 5/XCode 12.2 开始并使用 Apple's SimplePing code最后更新于 2016 年,他们没有。有些数据类型错误,有些参数标签不匹配,有些参数丢失。这意味着 SimplePingClient
永远不会得到它的回调,因为 SimplePing
在委托(delegate)对象中寻找匹配的签名,但没有找到,并跳过回调。
此外,因为 SimplePing.h
将这些委托(delegate)方法声明为可选,所以不会出现编译器错误。
要查看错误并让 XCode 为您编写协议(protocol) stub ,注释掉 SimplePing.h
中 SimplePingDelegate
定义中的@optional(行142).
为了让 SimplePingClient 正常工作,我需要对 SimplePingClient
类扩展进行更改:
extension SimplePingClient: SimplePingDelegate {
public func simplePing(_ pinger: SimplePing, didStartWithAddress address: Data) {
pinger.send(with: nil)
}
public func simplePing(_ pinger: SimplePing, didFailWithError error: Error) {
resultCallback?(nil)
}
public func simplePing(_ pinger: SimplePing, didSendPacket packet: Data, sequenceNumber:UInt16) {
dateReference = Date()
}
public func simplePing(_ pinger: SimplePing, didFailToSendPacket packet: Data, sequenceNumber: UInt16, error: Error) {
pinger.stop()
resultCallback?(nil)
}
public func simplePing(_ pinger: SimplePing, didReceiveUnexpectedPacket packet: Data) {
pinger.stop()
resultCallback?(nil)
}
public func simplePing(_ pinger: SimplePing, didReceivePingResponsePacket packet: Data, sequenceNumber:UInt16) {
pinger.stop()
guard let dateReference = dateReference else { return }
//timeIntervalSinceDate returns seconds, so we convert to milis
let latency = Date().timeIntervalSince(dateReference ) * 1000
resultCallback?(String(format: "%.f", latency))
}
}
关于ios - Swift SimplePing 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39719899/