Last active
November 14, 2016 05:48
Revisions
-
MatiMax revised this gist
Sep 30, 2016 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -54,7 +54,7 @@ class DNSResolve { //: Create a boolean pointer `DarwinBoolean` for use with the function `CFHostGetNames`. var resolved: DarwinBoolean = DarwinBoolean(false) //: Now get the results of the info resolution. let cfNames: CFArrayRef = CFHostGetNames(host!, &resolved)!.takeUnretainedValue() print("namesResolved: Names resolved: \(resolved) with error \(error.error)") //: We can use cascading casts from `[AnyObject]` to a force-unwrapped `[String]`. Thank you, Swift. self.names = cfNames as [AnyObject] as! [String] -
MatiMax revised this gist
Sep 28, 2016 . 1 changed file with 1 addition and 1 deletion.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -25,7 +25,7 @@ class DNSResolve { } //: Create the `CFHostRef` with the `CFData` object and store the retained value for later use. let hostref = CFHostCreateWithAddress(kCFAllocatorDefault, data) self.host = hostref.takeUnretainedValue() //: For the callback to work we have to create a client context. var ctx = CFHostClientContext( version: 0, -
MatiMax revised this gist
Sep 28, 2016 . No changes.There are no files selected for viewing
-
MatiMax created this gist
Sep 7, 2015 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,80 @@ //: # How to retrieve a host name and associated aliases from an IP address using Core Fondation's `CFHost` import Cocoa import XCPlayground //: In order to get the callback working we use a simple class to implement the showcase. class DNSResolve { //: The IP address may be a Swift `String` thanks to the toll-free bridging to C strings. let ip: String = "17.172.224.47" //: We use an optional `CFHost` variable because CFHost neither comes with an initializer nor is conforming to the Nullable protocol. var host: CFHost? //: We use this array of `String`s to store the resolved host names. var names: [String] = [] func resolve() { //: Let's set up the `sockaddr_in` C structure using the initializer. var sin = sockaddr_in( sin_len: UInt8(sizeof(sockaddr_in)), sin_family: sa_family_t(AF_INET), sin_port: in_port_t(0), sin_addr: in_addr(s_addr: inet_addr(ip)), sin_zero: (0,0,0,0,0,0,0,0) ) //: Now convert the structure into a `CFData` object. let data = withUnsafePointer(&sin) { ptr in CFDataCreate(kCFAllocatorDefault, UnsafePointer(ptr), sizeof(sockaddr_in)) } //: Create the `CFHostRef` with the `CFData` object and store the retained value for later use. let hostref = CFHostCreateWithAddress(kCFAllocatorDefault, data) self.host = hostref.takeRetainedValue() //: For the callback to work we have to create a client context. var ctx = CFHostClientContext( version: 0, info: unsafeBitCast(self, UnsafeMutablePointer<Void>.self), retain: nil, release: nil, copyDescription: unsafeBitCast(0, CFAllocatorCopyDescriptionCallBack.self) ) //: We can now set up the client for the callback using the `CFHostClientCallBack` signature for the closure. CFHostSetClient(host!, { (host, infoType, error, info) in let obj = unsafeBitCast(info, DNSResolve.self) print("Resolving …") obj.namesResolved(withError: error.memory) }, &ctx) //: Now schedule the runloop for the host. CFHostScheduleWithRunLoop(host!, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode); //: Create a `CFStreamError` object for use with the info resolution using `CFHostStartInfoResolution`. var error = CFStreamError() //: Start the info resolution. let started: Bool = CFHostStartInfoResolution(host!, .Names, &error) print("Name resolution started: \(started)") } //: This function is attachted as `CFHostClientCallBack` in `CFHostSetClient` which should get called during the info resolution. func namesResolved(withError error: CFStreamError) { print("namesResolved: Resolving …") //: Create a boolean pointer `DarwinBoolean` for use with the function `CFHostGetNames`. var resolved: DarwinBoolean = DarwinBoolean(false) //: Now get the results of the info resolution. let cfNames: CFArrayRef = CFHostGetNames(host!, &resolved)!.takeRetainedValue() print("namesResolved: Names resolved: \(resolved) with error \(error.error)") //: We can use cascading casts from `[AnyObject]` to a force-unwrapped `[String]`. Thank you, Swift. self.names = cfNames as [AnyObject] as! [String] //: **Oh dear—we see only one host name here and no aliases. Stuck again … :-(** print("CFArray reports \(CFArrayGetCount(cfNames)) elements, [String] reports \(self.names.count) elements.") self.listNames() //: After the info resolution clean up either way. CFHostSetClient(host!, nil, nil); CFHostCancelInfoResolution(host!, .Names) CFHostUnscheduleFromRunLoop(host!, CFRunLoopGetCurrent(), kCFRunLoopDefaultMode) } func listNames() { print(self.names) } } //: OK, let's create an instance of our `DNSResolve` class and run the `resolve()` method. let dnsRes = DNSResolve() dnsRes.resolve() //: In order to see the callback working we have to set Playground's execution to take on forever. XCPSetExecutionShouldContinueIndefinitely()