我正在尝试跟踪网络状态。我浏览了 FXReachability 的代码.具体有以下方法。
- (void)setHost:(NSString *)host
{
if (host != _host)
{
if (_reachability)
{
SCNetworkReachabilityUnscheduleFromRunLoop(_reachability, CFRunLoopGetMain(), kCFRunLoopCommonModes);
CFRelease(_reachability);
}
_host = [host copy];
_status = FXReachabilityStatusUnknown;
_reachability = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, [_host UTF8String]);
SCNetworkReachabilityContext context = { 0, ( __bridge void *)self, NULL, NULL, NULL };
SCNetworkReachabilitySetCallback(_reachability, ONEReachabilityCallback, &context);
SCNetworkReachabilityScheduleWithRunLoop(_reachability, CFRunLoopGetMain(), kCFRunLoopCommonModes);
}
}
它的作用是不断检查与指定主机的连接。我正在尝试将此方法转换为 Swift,但遇到了一些问题。
<强>1。将主机字符串转换为 UTF8。
我必须将主机字符串转换为 UTF8 并将其传递到 SCNetworkReachabilityCreateWithName方法。我在 Objective-C 中找不到与 UTF8String
属性完全相同的 Swift。但是 String
类型有一个名为 utf8
的属性。根据documentation ,
You can access a UTF-8 representation of a String by iterating over its utf8 property. This property is of type String.UTF8View, which is a collection of unsigned 8-bit (UInt8) values, one for each byte in the string’s UTF-8 representation:
如何获得字符串的完整 UTF8 表示而不是无符号 8 位 (UInt8) 值的集合?
<强>2。 SCNetworkReachabilitySetCallback 的回调函数.
此函数的第二个参数需要 SCNetworkReachabilityCallBack
类型的内容。我深入研究了源文件,发现它实际上是一个 typealias
。
typealias SCNetworkReachabilityCallBack = CFunctionPointer<((SCNetworkReachability!, SCNetworkReachabilityFlags, UnsafeMutablePointer<Void>) -> Void)>
我是这样定义的
let reachabilityCallBack: SCNetworkReachabilityCallBack = {
}()
但我收到错误Missing return in a closure expected to return 'SCNetworkReachabilityCallBack',当在该类型别名中时您可以清楚地看到它返回 Void
。
这是错误的做法吗?
这些是我面临的问题。我已经在这几个小时了,但没有运气,所以我真的很感激任何帮助。
谢谢。
最佳答案
你的第一个问题可以用
解决let reachability = host.withCString {
SCNetworkReachabilityCreateWithName(nil, $0).takeRetainedValue()
}
在封闭内部,$0
是指向以 NUL 结尾的 UTF-8 表示的指针
字符串。
更新:作为Nate Cook说在
现在已删除的答案,还有 here ,
您实际上可以将 Swift 字符串传递给采用 UnsafePointer<UInt8>
的函数
直接:
let reachability = SCNetworkReachabilityCreateWithName(nil, host).takeRetainedValue()
不幸的是(据我所知)目前没有解决您的第二个问题的方法。
SCNetworkReachabilitySetCallback
期望一个指向 C 函数的指针作为第二个
参数,目前还没有传递 Swift 函数或闭包的方法。
请注意 SCNetworkReachabilityCallBack
的文档
仅显示 Objective-C 但不显示 Swift。
另见 Does Swift not work with function pointers? .
Swift 2 更新:现在可以传递 Swift 闭包
到采用函数指针参数的 C 函数。还
SCNetworkReachabilityCreateWithName()
不再返回非托管对象:
let host = "google.com"
var context = SCNetworkReachabilityContext(version: 0, info: nil, retain: nil, release: nil, copyDescription: nil)
let reachability = SCNetworkReachabilityCreateWithName(nil, host)!
SCNetworkReachabilitySetCallback(reachability, { (_, flags, _) in
print(flags)
}, &context)
SCNetworkReachabilityScheduleWithRunLoop(reachability, CFRunLoopGetMain(), kCFRunLoopCommonModes)
Swift 3 (Xcode 8) 更新:
let host = "google.com"
var context = SCNetworkReachabilityContext(version: 0, info: nil, retain: nil, release: nil, copyDescription: nil)
let reachability = SCNetworkReachabilityCreateWithName(nil, host)!
SCNetworkReachabilitySetCallback(reachability, { (_, flags, _) in
print(flags)
}, &context)
SCNetworkReachabilityScheduleWithRunLoop(reachability, CFRunLoopGetMain(),
CFRunLoopMode.commonModes.rawValue)
关于ios - 在 Swift 中使用 C API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33972084/