Apples SinglePing 应用程序不调用委托方法
Apples SinglePing app doesn't call delegate methods
我正在尝试 SimplePing app from Apple。但是不会调用委托方法。我正在尝试寻找解决方案,但我也在这里寻求帮助。
谢谢。
这里是完整的 MainViewController class 看一下。
import UIKit
class MainViewController: UITableViewController, SimplePingDelegate {
let hostName = "www.apple.com"
override func viewDidLoad() {
super.viewDidLoad()
self.title = self.hostName
}
var pinger: SimplePing?
var sendTimer: Timer?
func start(forceIPv4: Bool, forceIPv6: Bool) {
self.pingerWillStart()
NSLog("start")
let pinger = SimplePing(hostName: self.hostName)
self.pinger = pinger
if (forceIPv4 && !forceIPv6) {
pinger.addressStyle = .icmPv4
} else if (forceIPv6 && !forceIPv4) {
pinger.addressStyle = .icmPv6
}
pinger.delegate = self
pinger.start()
}
func stop() {
NSLog("stop")
self.pinger?.stop()
self.pinger = nil
self.sendTimer?.invalidate()
self.sendTimer = nil
self.pingerDidStop()
}
func sendPing() {
self.pinger!.send(with: nil)
}
// MARK: pinger delegate callback
private func simplePing(pinger: SimplePing, didStartWithAddress address: NSData) {
NSLog("pinging %@", MainViewController.displayAddressForAddress(address: address))
self.sendPing()
assert(self.sendTimer == nil)
self.sendTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(MainViewController.sendPing), userInfo: nil, repeats: true)
}
private func simplePing(pinger: SimplePing, didFailWithError error: NSError) {
NSLog("failed: %@", MainViewController.shortErrorFromError(error: error))
self.stop()
}
private func simplePing(pinger: SimplePing, didSendPacket packet: NSData, sequenceNumber: UInt16) {
NSLog("#%u sent", sequenceNumber)
}
private func simplePing(pinger: SimplePing, didFailToSendPacket packet: NSData, sequenceNumber: UInt16, error: NSError) {
NSLog("#%u send failed: %@", sequenceNumber, MainViewController.shortErrorFromError(error: error))
}
private func simplePing(pinger: SimplePing, didReceivePingResponsePacket packet: NSData, sequenceNumber: UInt16) {
NSLog("#%u received, size=%zu", sequenceNumber, packet.length)
}
private func simplePing(pinger: SimplePing, didReceiveUnexpectedPacket packet: NSData) {
NSLog("unexpected packet, size=%zu", packet.length)
}
// MARK: utilities
static func displayAddressForAddress(address: NSData) -> String {
var hostStr = [Int8](repeating: 0, count: Int(NI_MAXHOST))
let success = getnameinfo(
address.bytes.assumingMemoryBound(to: sockaddr.self),
//UnsafePointer(address.bytes),
socklen_t(address.length),
&hostStr,
socklen_t(hostStr.count),
nil,
0,
NI_NUMERICHOST
) == 0
let result: String
if success {
result = String(cString: hostStr)
} else {
result = "?"
}
return result
}
/// Returns a short error string for the supplied error.
///
/// - parameter error: The error to render.
///
/// - returns: A short string representing that error.
static func shortErrorFromError(error: NSError) -> String {
if error.domain == kCFErrorDomainCFNetwork as String && error.code == Int(CFNetworkErrors.cfHostErrorUnknown.rawValue) {
if let failureObj = error.userInfo[kCFGetAddrInfoFailureKey] {
if let failureNum = failureObj as? NSNumber {
if failureNum.intValue != 0 {
let f = gai_strerror(Int32(failureNum.intValue))
if f != nil {
return String(cString: f!)
}
}
}
}
}
if let result = error.localizedFailureReason {
return result
}
return error.localizedDescription
}
// MARK: table view delegate callback
@IBOutlet var forceIPv4Cell: UITableViewCell!
@IBOutlet var forceIPv6Cell: UITableViewCell!
@IBOutlet var startStopCell: UITableViewCell!
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = self.tableView.cellForRow(at: indexPath as IndexPath)!
switch cell {
case forceIPv4Cell, forceIPv6Cell:
cell.accessoryType = cell.accessoryType == .none ? .checkmark : .none
case startStopCell:
if self.pinger == nil {
let forceIPv4 = self.forceIPv4Cell.accessoryType != .none
let forceIPv6 = self.forceIPv6Cell.accessoryType != .none
self.start(forceIPv4: forceIPv4, forceIPv6: forceIPv6)
} else {
self.stop()
}
default:
fatalError()
}
self.tableView.deselectRow(at: indexPath as IndexPath, animated: true)
}
func pingerWillStart() {
self.startStopCell.textLabel!.text = "Stop…"
}
func pingerDidStop() {
self.startStopCell.textLabel!.text = "Start…"
}
}
我已将它转换为 Swift 4 语法,但在模拟器或真实设备上没有任何效果。我点击 IPv4 或 IPv6 然后开始,但没有任何反应。
我从苹果下载了项目,自己试了一下。 table 视图的 didSelect 事件的方法签名可能有误。
确保更改
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
至
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
在 MainViewController.swift.
里面
希望这能解决您的问题。
编辑:您还需要更改 MainViewController.swift 中所有委托方法的签名。例如 func simplePing(pinger: SimplePing, didFailWithError error: NSError)
应该变成 func simplePing(_ pinger: SimplePing, didFailWithError error: Error)
.
我正在尝试 SimplePing app from Apple。但是不会调用委托方法。我正在尝试寻找解决方案,但我也在这里寻求帮助。
谢谢。
这里是完整的 MainViewController class 看一下。
import UIKit
class MainViewController: UITableViewController, SimplePingDelegate {
let hostName = "www.apple.com"
override func viewDidLoad() {
super.viewDidLoad()
self.title = self.hostName
}
var pinger: SimplePing?
var sendTimer: Timer?
func start(forceIPv4: Bool, forceIPv6: Bool) {
self.pingerWillStart()
NSLog("start")
let pinger = SimplePing(hostName: self.hostName)
self.pinger = pinger
if (forceIPv4 && !forceIPv6) {
pinger.addressStyle = .icmPv4
} else if (forceIPv6 && !forceIPv4) {
pinger.addressStyle = .icmPv6
}
pinger.delegate = self
pinger.start()
}
func stop() {
NSLog("stop")
self.pinger?.stop()
self.pinger = nil
self.sendTimer?.invalidate()
self.sendTimer = nil
self.pingerDidStop()
}
func sendPing() {
self.pinger!.send(with: nil)
}
// MARK: pinger delegate callback
private func simplePing(pinger: SimplePing, didStartWithAddress address: NSData) {
NSLog("pinging %@", MainViewController.displayAddressForAddress(address: address))
self.sendPing()
assert(self.sendTimer == nil)
self.sendTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(MainViewController.sendPing), userInfo: nil, repeats: true)
}
private func simplePing(pinger: SimplePing, didFailWithError error: NSError) {
NSLog("failed: %@", MainViewController.shortErrorFromError(error: error))
self.stop()
}
private func simplePing(pinger: SimplePing, didSendPacket packet: NSData, sequenceNumber: UInt16) {
NSLog("#%u sent", sequenceNumber)
}
private func simplePing(pinger: SimplePing, didFailToSendPacket packet: NSData, sequenceNumber: UInt16, error: NSError) {
NSLog("#%u send failed: %@", sequenceNumber, MainViewController.shortErrorFromError(error: error))
}
private func simplePing(pinger: SimplePing, didReceivePingResponsePacket packet: NSData, sequenceNumber: UInt16) {
NSLog("#%u received, size=%zu", sequenceNumber, packet.length)
}
private func simplePing(pinger: SimplePing, didReceiveUnexpectedPacket packet: NSData) {
NSLog("unexpected packet, size=%zu", packet.length)
}
// MARK: utilities
static func displayAddressForAddress(address: NSData) -> String {
var hostStr = [Int8](repeating: 0, count: Int(NI_MAXHOST))
let success = getnameinfo(
address.bytes.assumingMemoryBound(to: sockaddr.self),
//UnsafePointer(address.bytes),
socklen_t(address.length),
&hostStr,
socklen_t(hostStr.count),
nil,
0,
NI_NUMERICHOST
) == 0
let result: String
if success {
result = String(cString: hostStr)
} else {
result = "?"
}
return result
}
/// Returns a short error string for the supplied error.
///
/// - parameter error: The error to render.
///
/// - returns: A short string representing that error.
static func shortErrorFromError(error: NSError) -> String {
if error.domain == kCFErrorDomainCFNetwork as String && error.code == Int(CFNetworkErrors.cfHostErrorUnknown.rawValue) {
if let failureObj = error.userInfo[kCFGetAddrInfoFailureKey] {
if let failureNum = failureObj as? NSNumber {
if failureNum.intValue != 0 {
let f = gai_strerror(Int32(failureNum.intValue))
if f != nil {
return String(cString: f!)
}
}
}
}
}
if let result = error.localizedFailureReason {
return result
}
return error.localizedDescription
}
// MARK: table view delegate callback
@IBOutlet var forceIPv4Cell: UITableViewCell!
@IBOutlet var forceIPv6Cell: UITableViewCell!
@IBOutlet var startStopCell: UITableViewCell!
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = self.tableView.cellForRow(at: indexPath as IndexPath)!
switch cell {
case forceIPv4Cell, forceIPv6Cell:
cell.accessoryType = cell.accessoryType == .none ? .checkmark : .none
case startStopCell:
if self.pinger == nil {
let forceIPv4 = self.forceIPv4Cell.accessoryType != .none
let forceIPv6 = self.forceIPv6Cell.accessoryType != .none
self.start(forceIPv4: forceIPv4, forceIPv6: forceIPv6)
} else {
self.stop()
}
default:
fatalError()
}
self.tableView.deselectRow(at: indexPath as IndexPath, animated: true)
}
func pingerWillStart() {
self.startStopCell.textLabel!.text = "Stop…"
}
func pingerDidStop() {
self.startStopCell.textLabel!.text = "Start…"
}
}
我已将它转换为 Swift 4 语法,但在模拟器或真实设备上没有任何效果。我点击 IPv4 或 IPv6 然后开始,但没有任何反应。
我从苹果下载了项目,自己试了一下。 table 视图的 didSelect 事件的方法签名可能有误。
确保更改
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
至
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
在 MainViewController.swift.
希望这能解决您的问题。
编辑:您还需要更改 MainViewController.swift 中所有委托方法的签名。例如 func simplePing(pinger: SimplePing, didFailWithError error: NSError)
应该变成 func simplePing(_ pinger: SimplePing, didFailWithError error: Error)
.