Swift Question

How can I get a real IP address from DNS query in Swift?

I want to get the IP dress (like 192.168.0.1 or 87.12.56.50) from DNS query in

Swift
. I tried 100 times with 100 diffrent methods ... Nothing helped me, so I'll have to ask for help (I hope there are alots of folk here ;))
This is my code so far:

let host = CFHostCreateWithName(nil,"subdomain.of.stackoverflow.com").takeUnretainedValue();
CFHostStartInfoResolution(host, .Addresses, nil);
var success: Boolean = 0;
let addresses = CFHostGetAddressing(host, &success).takeUnretainedValue() as NSArray;
if(addresses.count > 0){
let theAddress = addresses[0] as NSData;
println(theAddress);
}


OK ... These are the links for the code I tried to implement without success:
https://gist.github.com/mikeash/bca3a341db74221625f5

How to perform DNS query on iOS

Create an Array in Swift from an NSData Object

Does CFHostGetAddressing() support ipv6 DNS entries?

Do a simple DNS lookup in Swift

So if we're done with nonsensical negative voting for this question we can try to find a solution and help other people (like me)

Answer

Your code retrieves the address as a "socket address" structure. getnameinfo() can be used to convert the address into a numerical IP string (code recycled from http://stackoverflow.com/a/25627545/1187415, now updated to Swift 2):

let host = CFHostCreateWithName(nil,"www.google.com").takeRetainedValue()
CFHostStartInfoResolution(host, .Addresses, nil)
var success: DarwinBoolean = false
if let addresses = CFHostGetAddressing(host, &success)?.takeUnretainedValue() as NSArray?,
    let theAddress = addresses.firstObject as? NSData {
    var hostname = [CChar](count: Int(NI_MAXHOST), repeatedValue: 0)
    if getnameinfo(UnsafePointer(theAddress.bytes), socklen_t(theAddress.length),
        &hostname, socklen_t(hostname.count), nil, 0, NI_NUMERICHOST) == 0 {
            if let numAddress = String.fromCString(hostname) {
                print(numAddress)
            }
    }
}

Output (example): 173.194.112.147

Note also the usage of takeRetainedValue() in the first line, because CFHostCreateWithName() has "Create" in its name the therefore returns a (+1) retained object.


Update for Swift 3/Xcode 8:

let host = CFHostCreateWithName(nil,"www.google.com" as CFString).takeRetainedValue()
CFHostStartInfoResolution(host, .addresses, nil)
var success: DarwinBoolean = false
if let addresses = CFHostGetAddressing(host, &success)?.takeUnretainedValue() as NSArray?,
    let theAddress = addresses.firstObject as? NSData {
    var hostname = [CChar](repeating: 0, count: Int(NI_MAXHOST))
    if getnameinfo(theAddress.bytes.assumingMemoryBound(to: sockaddr.self), socklen_t(theAddress.length),
                   &hostname, socklen_t(hostname.count), nil, 0, NI_NUMERICHOST) == 0 {
        let numAddress = String(cString: hostname)
        print(numAddress)
    }
}
Comments