简体   繁体   English

SCNetworkReachabilitySetCallback在Swift中失败

[英]SCNetworkReachabilitySetCallback failing in Swift

I'm attempting to use the following code to set a callback for an SCNetworkReachability 我正在尝试使用以下代码为SCNetworkReachability设置回调

// Create callback
let callback:(SCNetworkReachability!, SCNetworkReachabilityFlags, UnsafeMutablePointer<Void>) -> () = { (target: SCNetworkReachability!, flags: SCNetworkReachabilityFlags, info: UnsafeMutablePointer<Void>) in
    // Do something
}

// Create UnsafeMutablePointer and initialise with callback
let p = UnsafeMutablePointer<(SCNetworkReachability!, SCNetworkReachabilityFlags, UnsafeMutablePointer<Void>) -> Void>.alloc(1)
p.initialize(callback)

// convert UnsafeMutablePointer to COpaquePointer
let cp = COpaquePointer(p) 

// convert COppaquePointer to CFunctionPointer
let fp = CFunctionPointer<(SCNetworkReachability!, SCNetworkReachabilityFlags, UnsafeMutablePointer<Void>) -> Void>(cp)

if SCNetworkReachabilitySetCallback(reachability, fp, nil) != 0 {

    println(SCError()) // SCError() is returning 0
}

The SCNetworkReachabilitySetCallback call is failing - has anyone else had any success with this? SCNetworkReachabilitySetCallback调用失败 - 有没有其他人在这方面取得任何成功? Any idea where this might be wrong? 知道这可能是错的吗?

As of swift 1.2 you cannot pass functions written in swift using CFunctionPointer. 从swift 1.2开始,你不能使用CFunctionPointer传递用swift编写的函数。 It has mainly been introduced for passing around function pointers already defined in C to some other C (or objectiveC) routines. 它主要用于将已经在C中定义的函数指针传递给其他一些C(或objectiveC)例程。

One possible work around would be to use objc_block in swift eg: 一个可能的解决方法是在swift中使用objc_block,例如:

    let block: @objc_block (SCNetworkReachabilityRef, SCNetworkReachabilityFlags, UnsafePointer<Void>) -> Void = {
        [weak self]
        (reachability: SCNetworkReachabilityRef, flags: SCNetworkReachabilityFlags, data: UnsafePointer<Void>) in

        // Do something e.g. check if network reachability has changed

        if flags & SCNetworkReachabilityFlags(kSCNetworkReachabilityFlagsReachable) == 0 {

        }
    }

    let blockObject = imp_implementationWithBlock(unsafeBitCast(block, AnyObject.self))
    let fp = unsafeBitCast(blockObject, SCNetworkReachabilityCallBack.self)

    // e.g. you can use 169.254.0.0 for local wifi connection

    var reachability = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, ("169.254.0.0" as NSString).UTF8String).takeRetainedValue()
    var context = SCNetworkReachabilityContext()

    if SCNetworkReachabilitySetCallback(reachability!, fp, &context) == 1 {
        if SCNetworkReachabilityScheduleWithRunLoop(reachability!, CFRunLoopGetCurrent(), NSDefaultRunLoopMode) == 0 {
            println(SCError())
        }
    }

The SCNetworkReachabilitySetCallback function returns a Boolean. SCNetworkReachabilitySetCallback函数返回一个布尔值。

https://developer.apple.com/LIBRARY/ios/documentation/SystemConfiguration/Reference/SCNetworkReachabilityRef/index.html#//apple_ref/c/func/SCNetworkReachabilitySetCallback https://developer.apple.com/LIBRARY/ios/documentation/SystemConfiguration/Reference/SCNetworkReachabilityRef/index.html#//apple_ref/c/func/SCNetworkReachabilitySetCallback

The TRUE value is typically defined as 1. TRUE值通常定义为1。

Thus 从而

if SCNetworkReachabilitySetCallback(reachability, fp, nil) != 0 {

    println(SCError()) // SCError() is returning 0
}

would likely only ever print 0. 可能只会打印0。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM