Search code examples
iosswiftswift3reachability

SCNetworkReachabilityCallBack? type conversion issue with Swift3.0


As Swift 2.3 to Swift 3.0 conversion raise many issue, I am trying to solve this issue but not getting solution so far.

Cannot convert value of type '(SCNetworkReachability, flags: SCNetworkReachabilityFlags, info: UnsafeMutablePointer) -> ()' to expected argument type 'SCNetworkReachabilityCallBack?'

Here is my code :

func callback(_ reachability:SCNetworkReachability, flags: SCNetworkReachabilityFlags, info: UnsafeMutablePointer<Void>) {
    let reachability = Unmanaged<Reachability>.fromOpaque(info).takeUnretainedValue()

    DispatchQueue.main.async {
        reachability.reachabilityChanged(flags)
    }
}

In startNotifier function we are passing callback, but it generates error.

public func startNotifier() throws {

    guard !notifierRunning else { return }

    var context = SCNetworkReachabilityContext(version: 0, info: nil, retain: nil, release: nil, copyDescription: nil)
    context.info = UnsafeMutablePointer(Unmanaged.passUnretained(self).toOpaque())

    //THIS LINE GENERATES ERROR WARNING
    if !SCNetworkReachabilitySetCallback(reachabilityRef!, callback, &context) {
        stopNotifier()
        throw ReachabilityError.unableToSetCallback
    }

    if !SCNetworkReachabilitySetDispatchQueue(reachabilityRef!, reachabilitySerialQueue) {
        stopNotifier()
        throw ReachabilityError.unableToSetDispatchQueue
    }

    // Perform an intial check
    reachabilitySerialQueue.async { () -> Void in
        let flags = self.reachabilityFlags
        self.reachabilityChanged(flags)
    }

    notifierRunning = true
}

This code generates error in above function.

    //THIS LINE GENERATES ERROR WARNING
    if !SCNetworkReachabilitySetCallback(reachabilityRef!, callback, &context) {
        stopNotifier()
        throw ReachabilityError.unableToSetCallback
    }

enter image description here

I also go through this in depth post of Martin, but not getting solution. Any help should be appreciable. Thanks in Advance.


Solution

  • If you have something odd in Swift 3, always check the latest reference: (As for now, the latest reference is up to the latest Xcode 8, beta 6. If you are using beta 5 or older, the code below does not work.)

    Declaration

    typealias SCNetworkReachabilityCallBack = (
        SCNetworkReachability,
        SCNetworkReachabilityFlags,
        UnsafeMutableRawPointer?) -> Void
    

    The type of the last parameter of the call back has changed to UnsafeMutableRawPointer?.

    So, you may need to change your callback to something like this:

    func callback(_ reachability:SCNetworkReachability, flags: SCNetworkReachabilityFlags, info: UnsafeMutableRawPointer?) {
        let reachability = Unmanaged<Reachability>.fromOpaque(info!).takeUnretainedValue()
    
        DispatchQueue.main.async {
            reachability.reachabilityChanged(flags)
        }
    }