5

I'm currently using this code

    NSHost *host = [NSHost hostWithAddress:hostname];
if (host == nil) {
    host = [NSHost hostWithName:hostname];
    if (host == nil) {
        [self setMessage:@"Invalid IP address or hostname:"];
        return;
    }
}

to retrive my IP Address for a networking app I'm working on, however I'm aware that NSHost is a private API that will be rejected. Can anyone help me with working this code to produce the same results without using NSHost? I'm not really sure where to start.

EDIT:

Following suggestions that seem damn near perfect below I've added this code into my app in the place of the code above

    Boolean result;
CFHostRef hostRef;
CFArrayRef addresses;
NSString *hostname = @"www.apple.com";
hostRef = CFHostCreateWithName(kCFAllocatorDefault, (CFStringRef)hostname);
if (hostRef) {
    result = CFHostStartInfoResolution(hostRef, kCFHostAddresses, NULL); // pass an error instead of NULL here to find out why it failed
    if (result == TRUE) {
        addresses = CFHostGetAddressing(hostRef, &result);
    }
}
if (result == TRUE) {
    NSLog(@"Resolved");
} else {
    NSLog(@"Not resolved");
}

I've removed the 4th line (as I have this information from elsewhere already) but I get errors being based around CFHostRef being undeclared. How would I resolve that? It seems to be my only big hurdle, as other errors are only based upon the lack of being able to see hostRef after that. EDIT: Scratch that I also get kCFHostAddresses undeclared.

skaffman
  • 398,947
  • 96
  • 818
  • 769
David26th
  • 401
  • 2
  • 12
  • 26

3 Answers3

6

You can use CFHost to achieve the same. On the top of the CFHost Reference is a cookbook recipe for making the lookup.

The following code does very, very basic synchronous resolution (as yours above would with NSHost). Note that you don't want to do this since it can render your app unresponsive because it doesn't return until it's resolved or the timeout hits.

Use asynchronous lookup instead (CFHostSetClient and CFHostScheduleWithRunLoop as described in the CFHost documentation above). Also, depending on what you're planning to do, you may want to look into using the reachability APIs. Check out the WWDC sessions on networking available on the iPhone developer website.

Boolean result;
CFHostRef hostRef;
CFArrayRef addresses;
NSString *hostname = @"www.apple.com";
hostRef = CFHostCreateWithName(kCFAllocatorDefault, (CFStringRef)hostname);
if (hostRef) {
    result = CFHostStartInfoResolution(hostRef, kCFHostAddresses, NULL); // pass an error instead of NULL here to find out why it failed
    if (result == TRUE) {
        addresses = CFHostGetAddressing(hostRef, &result);
    }
}
if (result == TRUE) {
    NSLog(@"Resolved");
} else {
    NSLog(@"Not resolved");
}

// Don't forget to release hostRef when you're done with it
puzzle
  • 6,071
  • 1
  • 25
  • 30
  • Can you offer a little more direction to the specific recipe? I can't quite figure out which bit I'm looking at (not sat in front of my machine at the minute so struggling to see how it li ka to the rest of my code) – David26th Aug 08 '10 at 14:29
  • Edited above for a very simple synchronous example (which you should definitely not use unless you want your UI to freeze). – puzzle Aug 08 '10 at 15:13
  • Found this helpful for Bonjour advertised services. Can't quite get it to work for manually entered IP's which NSHost did. – David26th Aug 10 '10 at 18:00
  • @puzzle Your code comment is wrong. Releasing `addresses` may cause your app to crash. You retrieved addresses with a **get** method and CoreFoundation guidelines say that you must not release values retrieved by a get method. You only release values returned by a method with **create** or **copy** in its name and if you have retained them yourself (using `CFRetain`). The returned array is actually owned by `CFHost` and it just returns a ref to the array to you (it does not retain it first - Apples `CFHost.c` is open source, you can verify that yourself). – Mecki Apr 17 '13 at 18:44
  • Probably better to show an async example rather than leading people down a path that can lead to their app hanging and Apple rejecting it. :-) – dgatwood Sep 22 '15 at 23:10
  • @dgatwood The question was specifically about a non-private API replacement for NSHost, which is synchronous. As you may have noted, everything past the first sentence of my answer is an explanation why this is probably a bad idea ;) Edited to make these parts bold, in case anyone is still overlooking them... – puzzle Sep 24 '15 at 21:24
  • I still don't see the ip addess. Its a CFArray object. After conversion, it still gives the non readable output. – nr5 Sep 14 '17 at 11:53
  • CFHost reference is broken. This is the correct link now: https://developer.apple.com/documentation/cfnetwork/cfhost – Dave Nottage Mar 06 '18 at 05:33
0

Look at this: http://blog.zachwaugh.com/post/309927273/programmatically-retrieving-ip-address-of-iphone

Andrew Kovzel
  • 601
  • 5
  • 7
  • Wollongong look at implementing this tomorrow when i have my laptop with me. Working on my ipad ring now. – David26th Aug 08 '10 at 14:29
  • Note that this is for getting the iPhone's own IP address while you seem to be looking for resolving a hostname, at least from how I read your question. – puzzle Aug 08 '10 at 14:57
  • Actually you may be on something here xtina. I only glanced back at my code after receiving the rejection from apple so may need to check. How would I do this if I wanted to resolve a hostname? – David26th Aug 08 '10 at 15:01
  • This comment was just about the example Andrew linked. I edited my original answer above to clarify how to do what you did with NSHost with CFHost instead. – puzzle Aug 08 '10 at 15:16
-3

http://developer.apple.com/iphone/library/qa/qa2009/qa1652.html

Got a great little answer through the Developer Support system, this worked perfectly.

David26th
  • 401
  • 2
  • 12
  • 26