Working with C APIs from Swift

前端 未结 1 1072
慢半拍i
慢半拍i 2020-11-27 21:18

I\'m trying to keep track of the network status. I went through the code of the FXReachability. Specifically the following method.

- (void)setHost:(NSString          


        
相关标签:
1条回答
  • 2020-11-27 21:59

    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)
    
    0 讨论(0)
提交回复
热议问题