2014-09-17 10 views
8

Desidero ottenere l'IP dress (come 192.168.0.1 o 87.12.56.50) dalla query DNS in Swift. Ho provato 100 volte con 100 metodi diffrent ... Niente mi ha aiutato, quindi dovrò chiedere aiuto (mi ci speranza sono alots di folk qui;)) Questo è il mio codice finora:Come posso ottenere un indirizzo IP reale dalla query DNS in Swift?

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 ... Questi sono i link per il codice che ho cercato di attuare senza successo: 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
Quindi, se abbiamo finito con negat senza senso Se voto per questa domanda, possiamo provare a trovare una soluzione e aiutare altre persone (come me)

risposta

23

Il tuo codice recupera l'indirizzo come una struttura "indirizzo socket". getnameinfo() può essere utilizzato per convertire l'indirizzo in una stringa IP numerico (codice riciclo https://stackoverflow.com/a/25627545/1187415, ora aggiornati 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) 
      } 
    } 
} 

uscita (esempio): 173.194.112.147

Nota anche l'utilizzo di takeRetainedValue() nella prima riga, perché CFHostCreateWithName() ha "Crea" nel suo nome e pertanto restituisce un oggetto (+1) mantenuto .


Aggiornamento per 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) 
    } 
} 

Oppure, per ottenere tutte le gli indirizzi IP per l'host:

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? { 
    for case let theAddress as NSData in addresses { 
     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) 
     } 
    } 
} 
+0

OMG! Funziona ... :) –

+0

Tu sei l'uomo! Sono molto nuovo a Swift e credimi ... hai aggiunto solo 5 righe al mio codice, ma non ne capisco una parola. Quindi mi hai salvato il tempo. Non lo farei da solo! Grazie! –

+0

@ ХристоАтанасов: Quindi dovresti leggere la documentazione su getnameinfo() e tutte quelle cose finché non la capisci :) –