Working with C APIs from Swift

Your first problem can be solved with

let reachability = host.withCString {
    SCNetworkReachabilityCreateWithName(nil, $0).takeRetainedValue()
}

Inside the closure, $0 is a pointer to the NUL-terminated UTF-8 representation of the
String.

Update: As Nate Cook said in
a now deleted answer and also here,
you can actually pass a Swift string to a function taking a UnsafePointer<UInt8>
directly:

let reachability = SCNetworkReachabilityCreateWithName(nil, host).takeRetainedValue()

Unfortunately there is (as far as I know) currently no solution to your second problem.
SCNetworkReachabilitySetCallback expects a pointer to a C function as second
parameter, and there is currently no method to pass a Swift function or closure.
Note that the documentation for SCNetworkReachabilityCallBack
shows only Objective-C but no Swift.

See also Does Swift not work with function pointers?.


Update for Swift 2: It is now possible to pass a Swift closure
to a C function taking a function pointer parameter. Also
SCNetworkReachabilityCreateWithName()
does not return an unmanaged object anymore:

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)

Update for 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)

Leave a Comment