简体   繁体   中英

SCNetworkReachabilitySetCallback failing in Swift

I'm attempting to use the following code to set a callback for an 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? Any idea where this might be wrong?

As of swift 1.2 you cannot pass functions written in swift using CFunctionPointer. It has mainly been introduced for passing around function pointers already defined in C to some other C (or objectiveC) routines.

One possible work around would be to use objc_block in swift eg:

    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.

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.

Thus

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

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

would likely only ever print 0.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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