Todd
Todd

Reputation: 1953

Reading TXT Record in iOS

I'm slowly learning to code for networks and have come to a bit of a dead end: I thought that by accessing the TXT Record of a nas drive I'd be able to see the volumes it offered as described at:

http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt

But when I run this code:

browse = [[NSNetServiceBrowser alloc]init];
[browse setDelegate:self];
[browse searchForServicesOfType:@"_afpovertcp._tcp." inDomain:@"local"];

To set up a search for sevices and the following for the callback:

-(void)netServiceBrowser:(NSNetServiceBrowser *)aNetServiceBrowser didFindService:(NSNetService *)aNetService moreComing:(BOOL)moreComing
{
    NSLog(@"Found: %@",aNetService);
    CFNetServiceRef aCFNetRef;
    aCFNetRef = CFNetServiceCreate(kCFAllocatorDefault, (__bridge CFStringRef)[aNetService domain],(__bridge CFStringRef) [aNetService type], (__bridge CFStringRef)[aNetService name], 0);
    CFStreamError error;
    if (CFNetServiceResolveWithTimeout(aCFNetRef, timeOut, &error)) {
        NSLog(@"CFNET TXT: %@",CFNetServiceGetTXTData(aCFNetRef));
        }
    }
    NSLog(@"TXTRecord: %@",[NSNetService dictionaryFromTXTRecordData:[aNetService TXTRecordData]]);       
    if (!moreComing) {
        [browse stop];
        [refreshButton setEnabled:YES];
        [self reloadInputViews];
    }
}

The nslog() lines show that the TXT Record of the found service is empty: I get something along the lines of

Found: <NSNetService 0x6a90fd0> local. _afpovertcp._tcp. myLocalSVR
CFNET TXT: <00>
TXTRecord: (null)

Can someone say whether I've got the code right or is it just that the local nas here doesn't containt a TXT Record - from what I've read, though, this just shouldn't be the case. I've also read that the service needs to be resolved before a TXT Record is coughed up, but I was hoping that that's what the CFNetServiceResolveWithTimeout() is doing...

Thanks!

Todd.

Upvotes: 1

Views: 2471

Answers (2)

Matt__C
Matt__C

Reputation: 329

I know this is an old question but just worked this out myself.

The TXTRecordData is not available until the netServiceDidResolveAddress is called. Eg:

- (void)netServiceDidResolveAddress:(NSNetService *)service {

    NSData* data = [service TXTRecordData];
    NSDictionary* dict = [NSNetService dictionaryFromTXTRecordData:data];

You are checking at the didFindService point but any calls before the address is resolved will return nil.

Upvotes: 1

itorres
itorres

Reputation: 360

From the document you link to (http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt), emphasis mine:

The intention of DNS-SD TXT records is to convey a small amount of useful additional information about a service. Ideally it should not
be necessary for a client to retrieve this additional information
before it can usefully establish a connection to the service. For a well-designed application protocol, even if there is no information
at all in the TXT record, it should be possible, knowing only the
host name, port number, and protocol being used, to communicate with
that listening process, and then perform version- or feature-
negotiation to determine any further options or capabilities of the
service instance
. For example, when connecting to an Apple Filing
Protocol (AFP) [AFP] server over TCP, the client enters into a
protocol exchange with the server to determine which version of AFP
the server implements, and which optional features or capabilities
(if any) are available.

I understand that the proper thing to do is establish an AFP session with the discovered server to list the shares.

You can check the TXT records of the NAS with dns-sd -L:

dns-sd -L name type domain
look up and display the information necessary to contact and use the named service: the hostname of the machine where that service is available, the port number on which the service is listening, and (if present) TXT record attributes describing properties of the service.

Doing an _afpovertcp query on my local network I get:

$ dns-sd -L mir _afpovertcp._tcp. local.
Lookup mir._afpovertcp._tcp..local.
 1:14:40.948  mir._afpovertcp._tcp.local. can be reached at mir.local.:548 (interface 4) Flags: 1
 1:14:40.948  mir._afpovertcp._tcp.local. can be reached at mir.local.:548 (interface 5) Flags: 1
 1:14:40.948  mir._afpovertcp._tcp.local. can be reached at mir.local.:548 (interface 9) Flags: 1
 1:14:40.948  mir._afpovertcp._tcp.local. can be reached at mir.local.:548 (interface 10) Flags: 1
 1:14:40.948  mir._afpovertcp._tcp.local. can be reached at mir.local.:548 (interface 11) Flags: 1
 1:14:40.948  mir._afpovertcp._tcp.local. can be reached at mir.local.:548 (interface 12)

Hope this helps.

Upvotes: 1

Related Questions