NSNetServiceBrowsing cannot resolve Services with Error -72004

652 Views Asked by At

For a couple of days I try to implement a App that browses for Bonjour-Services in my Network and display them in the Console (for the first step). I implemented a class with a NSNetServiceBrowser and initialized it as indicated in many posts here. But after finding the Service i cannot resolve it to make the hostname accessible for me. Service-resolving always leads in an error

-72004 (NSNetServicesBadArgumentError).

I tried to use @"local." as domain or my specific service to finde instead of @"_services._dns-sd._udp." but this all leads to the same result.

//
//  Bonjour.m
//  BonjourTest 
//
//  Created by PellePe on 21.07.18.
//  Copyright © 2018 PellePe. All rights reserved.
//

#import "Bonjour.h"
#import <Foundation/Foundation.h>

#include <netinet/in.h>


#define SERVICE_DOMAIN @"local"
#define SERVICE_TYPE   @"_bonjourTest._tcp"
#define SERVICE_NAME   @"Bonjour Test"

@interface Bonjour () <NSNetServiceDelegate, NSNetServiceBrowserDelegate>

@property (nonatomic, strong) NSMutableArray<NSNetService *> *detectedServices;
@property (nonatomic, strong) NSNetServiceBrowser *netServiceBrowser;

@end


@implementation Bonjour

#pragma mark -
#pragma mark Service Browsing

- (BOOL)isBrowsing {
    return self.netServiceBrowser != NULL;
}

- (void)startServiceBrowsing:(NSString *)type {
    if (self.detectedServices == NULL) {
        self.detectedServices = [[NSMutableArray<NSNetService*> alloc] init];
    } else {
        [self.detectedServices removeAllObjects];
    }

    self.netServiceBrowser = [[NSNetServiceBrowser alloc] init];
    self.netServiceBrowser.includesPeerToPeer = YES;
    self.netServiceBrowser.delegate = self;

    [self.netServiceBrowser searchForServicesOfType: type  // SERVICE_TYPE
                                       inDomain: @""];
}

- (void)stopServiceBrowsing {
    assert(self.netServiceBrowser != NULL);

    [self.netServiceBrowser stop];
    self.netServiceBrowser = NULL;
}

#pragma mark -
#pragma NSNetServiceDelegate

-(void)netServiceWillResolve:(NSNetService *)sender {
    NSLog(@"netService will resolve - %@", sender.hostName);
}

- (void)netService:(NSNetService *)sender
     didNotResolve:(NSDictionary<NSString *,NSNumber *> *)errorDict {
    NSLog(@"netService did not resolve");

    for (NSString *key in [errorDict allKeys]) {
        NSLog(@"%@: %@", key, [errorDict objectForKey: key]);
    }
}

- (void)netServiceDidResolveAddress:(NSNetService *)sender {
    NSLog(@"netService did resolve address - %@", sender.hostName);  
}

#pragma mark -
#pragma mark NSNetServiceBrowserDelegate

- (void)netServiceBrowserWillSearch:(NSNetServiceBrowser *)browser {
    NSLog(@"Browser will search");
}

- (void)netServiceBrowserDidStopSearch:(NSNetServiceBrowser *)browser {
    NSLog(@"Browser did stop search");
}

- (void)netServiceBrowser:(NSNetServiceBrowser *)browser     didFindService:(NSNetService *)service moreComing:(BOOL)moreComing {
    [self.detectedServices addObject: service];

    service.delegate = self;
    [service resolveWithTimeout: 100];

    NSLog(@"Find service: %@ - %@ - %@ (%@)", service.name, service.hostName, service.type, moreComing ? @"YES" : @"No");
}

- (void)netServiceBrowser:(NSNetServiceBrowser *)browser didRemoveService:(NSNetService *)service moreComing:(BOOL)moreComing {
    NSLog(@"Remove service: %@ - %@ - %@", service.name, service.hostName, service.type);
}

@end

I searched the net for many hours but couldn't find any hint on the error -72004. Using the NSNetServiceBrowser i have no influence on how the services are initialized.

Does anyone have an idea what goes wrong with it?

1

There are 1 best solutions below

0
Alexandre Mantovani Tavares On

So the problem here is that when you search for _services._dns-sd._udp. you won't get the actual services, but you will get all the service types, so for example.

let browser = NetServiceBrowser()
browser.searchForServices(ofType: "_googlecast._tcp", inDomain: "local")

This query will return services that will look like this

NetService(domain: "local", type: "_googlecast._tcp", name: "RoomTV")

and this is valid and you can resolve without problems, but when you browse like this:

browser.searchForServices(ofType: "_services._dns-sd._udp.", inDomain: "local")

the returned service will look like the following:

NetService(domain: ".", type: "_tcp.local.", name: "_googlecast")

So to fix that you need to search again with the new type to get the actual services.

let type = "\(service.name).\(service.type)"
               .replacingOccurrences(of: "local.", with: "")
browser.searchForServices(ofType: type, inDomain: "local")